답변:
현재 디렉토리가 다음과 같은 경우 다음을 수행 할 수 있습니다 parent_directory
.
for d in [0-9][0-9][0-9]
do
( cd "$d" && your-command-here )
done
(
하고 )
현재 디렉토리가 기본 스크립트에서 변경되지 않도록, 서브 쉘을 만들 수 있습니다.
for f in foo bar; do cat "$f"/*.txt; done >output
기능적으로 cat foo/*.txt bar/*.txt >output
. 그러나 ls
인수를 전달하는 방법에 따라 약간 다른 출력을 생성하는 하나의 명령입니다. 마찬가지로, 하위 디렉토리에서 파일을 실행할 경우 grep
또는 wc
상대 파일 이름을 출력하는 또는는 다른 파일 이름이 달라집니다 (그러나 종종 그런 이유로 하위 디렉토리로 정확하게 들어 가지 않기를 원합니다).
find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd" \;
\( ! -name . \)
현재 디렉토리에서 명령을 실행 피한다.
find FOLDER* -maxdepth 0 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd" \;
-exec bash -c 'cd "$0" && pwd' {} \;
일부 디렉토리에는 작은 따옴표와 큰 따옴표가 포함되어 있기 때문에 해야했습니다 .
-mindepth 1
pwd
직접 받는 것이 아니라 ?
disd(){find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c 'cd "{}" && "$@"' \;}
작동하지.
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에서 요청한대로) 공백이있는 이름을 구분합니다.
또한보십시오:
find
명시 적 루프를 사용하지 않고 배열에 출력을 넣는 유일한 올바른 방법 은 Bash 4.4에서 사용할 수 있습니다 mapfile -t -d '' dirs < <(find . -type d -print0)
. 그때까지 유일한 옵션은 루프를 사용하는 것입니다 (또는 작업을으로 연기 find
).
dirs
배열 이 필요하지 않습니다 . 다음 find
과 같이 (안전하게) 출력을 반복 할 수 find . -type d -print0 | while IFS= read -r -d '' file; do ...; done
있습니다.
IFS
과 read
(당신이 말한대로) 익숙해지면 두 번째 본질이됩니다 ... 이는 스크립트를 작성하는 정식적이고 관용적 인 방법의 일부입니다.
find . -type d -execdir echo $(pwd)/{} ';'
당신이합니다 (원하는 것을하지 않는 $(pwd)
이전 확장 find
... 심지어 실행)
최상위 폴더가 알려진 경우 다음과 같이 작성할 수 있습니다.
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"를하지 않았다.
건배,
ls
" 의 몇 가지 예가 있습니다 for dir in $YOUR_TOP_LEVEL_FOLDER/*
. 대신 할 수 있습니다 .
ls $dir
하나의 라이너는 빠르고 더러운 사용법에 좋지만 스크립트 작성에 더 자세한 버전을 선호합니다. 이것은 내가 사용하는 템플릿으로 많은 경우를 처리하며 폴더에서 실행할 더 복잡한 코드를 작성할 수 있습니다. 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"
당신이 사용할 수있는
find .
현재 디렉토리 재귀에서 모든 파일 / 디렉토리를 검색하려면
출력을 xargs 명령으로 파이프 할 수있는 것보다
find . | xargs 'command here'
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
cd
서브 쉘에서 수행해야합니다 .
cd
이 코드는 실제로 유용한 작업을 수행하지 않으므로 편집 내용이 손실되었습니다 .
cd "$d"
와일드 카드가 이름에 공백 및 / 또는 쉘 메타 문자가 포함 된 파일과 일치하는 상황으로 전송한다는 점에서 더 좋습니다.