태그 보관물: unix

unix

각 디렉토리로 이동하여 명령을 실행하는 방법은 무엇입니까? 디렉토리를 통과하고 bash는 스크립트 작성합니까 실행 명령

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

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

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

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

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



답변

현재 디렉토리가 다음과 같은 경우 다음을 수행 할 수 있습니다 parent_directory.

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

(하고 )현재 디렉토리가 기본 스크립트에서 변경되지 않도록, 서브 쉘을 만들 수 있습니다.


답변

Todd가 게시 한이 답변 이 도움이되었습니다.

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

\( ! -name . \) 현재 디렉토리에서 명령을 실행 피한다.


답변

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 포함 ) :

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

위의 예는 현재 dir을 무시하지만 (OP에서 요청한대로) 공백이있는 이름을 구분합니다.

또한보십시오:


답변

파이핑 한 다음을 사용하여이 작업을 수행 할 수 있습니다 xargs. catch는 -Ibash 명령의 하위 문자열을 각각이 전달한 하위 문자열로 대체 하는 플래그 를 사용해야 합니다 xargs.

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

pwd각 디렉토리에서 실행하려는 명령 으로 바꿀 수 있습니다 .


답변

최상위 폴더가 알려진 경우 다음과 같이 작성할 수 있습니다.

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

$ (원하는대로 플레이); 원하는만큼 코드를 넣을 수 있습니다.

나는 어떤 디렉토리에서도 “cd”를하지 않았다.

건배,


답변

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


답변

하나의 라이너는 빠르고 더러운 사용법에 좋지만 스크립트 작성에 더 자세한 버전을 선호합니다. 이것은 내가 사용하는 템플릿으로 많은 경우를 처리하며 폴더에서 실행할 더 복잡한 코드를 작성할 수 있습니다. dir_command 함수에서 bash 코드를 작성할 수 있습니다. 아래에서 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"