programing

각 디렉터리로 이동하여 명령을 실행하는 방법은 무엇입니까?

bestprogram 2023. 5. 12. 22:49

각 디렉터리로 이동하여 명령을 실행하는 방법은 무엇입니까?

parent_directory 내의 각 디렉토리를 통과하고 각 디렉토리에서 명령을 실행하는 bash 스크립트를 작성하려면 어떻게 해야 합니까?

디렉토리 구조는 다음과 같습니다.

parent_directory(이름은 무엇이든 될 수 있음 - 패턴을 따르지 않음)

  • 001(디렉토리 이름은 이 패턴을 따릅니다)
    • 0001.txt(파일 이름은 이 패턴을 따릅니다)
    • 0002.txt
    • 0003.txt
  • 002
    • 0001.txt
    • 0002.txt
    • 0003.txt
    • 0004.txt
  • 003
    • 0001.txt

디렉터리 수를 알 수 없습니다.

토드가 올린답변이 저에게 도움이 되었습니다.

find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd" \;

\( ! -name . \)현재 디렉터리에서 명령을 실행하지 않도록 합니다.

현재 디렉터리가 다음과 같을 때 다음을 수행할 수 있습니다.parent_directory:

for d in [0-9][0-9][0-9]
do
    ( cd "$d" && your-command-here )
done

(그리고.)기본 스크립트에서 현재 디렉토리가 변경되지 않도록 하위 셸을 만듭니다.

파이프를 사용하여 이를 달성할 수 있습니다.xargs문제점은 당신이 그것을 사용해야 한다는 것입니다.-Ibash 명령의 하위 문자열을 각각이 전달하는 하위 문자열로 바꿀 플래그xargs.

ls -d */ | xargs -I {} bash -c "cd '{}' && pwd"

교체할 수 있습니다.pwd각 디렉토리에서 실행할 명령을 사용합니다.

GNU를 사용하는 경우find해볼 수 있습니다-execdir매개변수(예:

find . -type d -execdir realpath "{}" ';'

또는 (@gniourf_gniourf 주석에 따라):

find . -type d -execdir sh -c 'printf "%s/%s\n" "$PWD" "$0"' {} \;

참고: 사용할 수 있습니다.${0#./}대신에$0고쳐야 할./맨 앞에

또는 보다 실질적인 예:

find . -name .git -type d -execdir git pull -v ';'

현재 디렉터리를 포함하려면 다음을 사용하는 것이 훨씬 더 간단합니다.-exec:

find . -type d -exec sh -c 'cd -P -- "{}" && pwd -P' \;

또는 사용xargs:

find . -type d -print0 | xargs -0 -L1 sh -c 'cd "$0" && pwd && echo Do stuff'

또는 @gniourf_gniourf에 의해 제안된 유사한 예:

find . -type d -print0 | while IFS= read -r -d '' file; do
# ...
done

위의 예는 이름에 공백이 있는 디렉토리를 지원합니다.


또는 bash 어레이에 할당함으로써:

dirs=($(find . -type d))
for dir in "${dirs[@]}"; do
  cd "$dir"
  echo $PWD
done

바꾸다.특정 폴더 이름으로 이동합니다.재귀적으로 실행할 필요가 없는 경우 다음을 사용할 수 있습니다.dirs=(*)대신.위의 예에서는 이름에 공백이 있는 디렉토리를 지원하지 않습니다.

따라서 @gniourf_gniourf가 제안한 것처럼 명시적 루프를 사용하지 않고 find의 출력을 배열에 넣을 수 있는 유일한 방법은 Bash 4.4에서 다음과 같습니다.

mapfile -t -d '' dirs < <(find . -type d -print0)

또는 권장되지 않는 방법(의 구문 분석 포함):

ls -d */ | awk '{print $NF}' | xargs -n1 sh -c 'cd $0 && pwd && echo Do stuff'

위의 예는 OP의 요청에 따라 현재 dir를 무시하지만 공백이 있는 이름에서는 중단됩니다.

참고 항목:

최상위 폴더를 알고 있는 경우 다음과 같은 내용을 작성할 수 있습니다.

for dir in `ls $YOUR_TOP_LEVEL_FOLDER`;
do
    for subdir in `ls $YOUR_TOP_LEVEL_FOLDER/$dir`;
    do
      $(PLAY AS MUCH AS YOU WANT);
    done
done

$(PLAY ASMUSY YOURSELF)에서 원하는 만큼의 코드를 넣을 수 있습니다.

참고로 저는 어떤 디렉토리에서도 "cd"를 하지 않았습니다.

건배.

for dir in PARENT/*
do
  test -d "$dir" || continue
  # Do something with $dir...
done

하나의 라이너는 빠르고 더러운 사용에 좋지만, 스크립트 작성을 위해 아래의 더 자세한 버전을 선호합니다.이것은 많은 에지 케이스를 처리하고 폴더에서 실행할 더 복잡한 코드를 작성할 수 있게 해주는 제가 사용하는 템플릿입니다.bash 코드는 function dir_command에 기록할 수 있습니다.아래에서 dir_coomand는 각 리포지토리 git에 태그를 지정하여 예제로 구현합니다.나머지 스크립트에서는 디렉터리의 각 폴더에 대해 dir_command를 호출합니다.주어진 폴더 집합을 통해서만 반복하는 예도 포함됩니다.

#!/bin/bash

#Use set -x if you want to echo each command while getting executed
#set -x

#Save current directory so we can restore it later
cur=$PWD
#Save command line arguments so functions can access it
args=("$@")

#Put your code in this function
#To access command line arguments use syntax ${args[1]} etc
function dir_command {
    #This example command implements doing git status for folder
    cd $1
    echo "$(tput setaf 2)$1$(tput sgr 0)"
    git tag -a ${args[0]} -m "${args[1]}"
    git push --tags
    cd ..
}

#This loop will go to each immediate child and execute dir_command
find . -maxdepth 1 -type d \( ! -name . \) | while read dir; do
   dir_command "$dir/"
done

#This example loop only loops through give set of folders    
declare -a dirs=("dir1" "dir2" "dir3")
for dir in "${dirs[@]}"; do
    dir_command "$dir/"
done

#Restore the folder
cd "$cur"

폴더를 통해서만 반복하기를 원하기 때문에 파일 형식에 대한 요점을 모르겠습니다.당신은 이런 것을 찾고 있습니까?

cd parent
find . -type d | while read d; do
   ls $d/
done

사용할 수 있습니다.

find .

현재 디렉터리에 있는 모든 파일/파일을 반복적으로 검색합니다.

당신은 xargs 명령어의 출력을 파이프로 연결할 수 있습니다.

find . | xargs 'command here'
  #!/bin.bash
for folder_to_go in $(find . -mindepth 1 -maxdepth 1 -type d \( -name "*" \) ) ; 
                                    # you can add pattern insted of * , here it goes to any folder 
                                    #-mindepth / maxdepth 1 means one folder depth   
do
cd $folder_to_go
  echo $folder_to_go "########################################## "
  
  whatever you want to do is here

cd ../ # if maxdepth/mindepath = 2,  cd ../../
done

#you can try adding many internal for loops with many patterns, this will sneak anywhere you want

다음과 같이 각 폴더에서 명령 시퀀스를 한 줄로 실행할 수 있습니다.

for d in PARENT_FOLDER/*; do (cd "$d" && tar -cvzf $d.tar.gz *.*)); done
for p in [0-9][0-9][0-9];do
    (
        cd $p
        for f in [0-9][0-9][0-9][0-9]*.txt;do
            ls $f; # Your operands
        done
    )
done

언급URL : https://stackoverflow.com/questions/7470165/how-to-go-to-each-directory-and-execute-a-command