TL; DR : 가장 정확한 답변을 위해 여기에 온다면 내 개인적인 취향을 원할 것 find . -name '*.txt' -exec process {} \;
입니다 (이 글의 하단 참조). 시간이 있다면 나머지 부분을 읽고 여러 가지 다른 방법과 대부분의 문제를 확인하십시오.
전체 답변 :
가장 좋은 방법은 수행하려는 작업에 따라 다르지만 몇 가지 옵션이 있습니다. 하위 트리의 파일이나 폴더에 이름에 공백이없는 경우 파일을 반복 할 수 있습니다.
for i in $x; do # Not recommended, will break on whitespace
process "$i"
done
조금 더 나은 임시 변수를 잘라내십시오 x
.
for i in $(find -name \*.txt); do # Not recommended, will break on whitespace
process "$i"
done
당신이 할 수있을 때 glob하는 것이 훨씬 좋습니다. 현재 디렉토리의 파일에 대한 공백 안전 :
for i in *.txt; do # Whitespace-safe but not recursive.
process "$i"
done
이 globstar
옵션 을 활성화하면 이 디렉토리와 모든 하위 디렉토리에서 일치하는 모든 파일을 가져올 수 있습니다.
# Make sure globstar is enabled
shopt -s globstar
for i in **/*.txt; do # Whitespace-safe and recursive
process "$i"
done
예를 들어 파일 이름이 이미 파일에있는 경우 read
다음 을 사용해야합니다 .
# IFS= makes sure it doesn't trim leading and trailing whitespace
# -r prevents interpretation of \ escapes.
while IFS= read -r line; do # Whitespace-safe EXCEPT newlines
process "$line"
done < filename
read
find
구분 기호를 적절하게 설정하여 다음 과 같이 안전하게 사용할 수 있습니다 .
find . -name '*.txt' -print0 |
while IFS= read -r -d '' line; do
process "$line"
done
보다 복잡한 검색의 경우 옵션 또는 다음과 find
함께을 사용하는 것이 -exec
좋습니다 -print0 | xargs -0
.
# execute `process` once for each file
find . -name \*.txt -exec process {} \;
# execute `process` once with all the files as arguments*:
find . -name \*.txt -exec process {} +
# using xargs*
find . -name \*.txt -print0 | xargs -0 process
# using xargs with arguments after each filename (implies one run per filename)
find . -name \*.txt -print0 | xargs -0 -I{} process {} argument
find
또한 -execdir
대신을 사용하여 명령을 실행하기 전에 각 파일의 디렉토리에 CD를 넣을 -exec
수 있으며 -ok
대신 -exec
(또는 -okdir
대신 )을 사용하여 대화식 (각 파일에 대해 명령을 실행하기 전에 프롬프트)으로 만들 수 있습니다 -execdir
.
* : 기술적으로 find
and xargs
(기본적으로)는 모든 파일을 처리하는 데 걸리는 횟수만큼 명령 줄에 입력 할 수있는 인수 수만큼 명령을 실행합니다. 실제로 파일 수가 매우 많지 않은 한 중요하지 않으며 길이를 초과하지만 동일한 명령 줄에 모두 필요한 경우 SOL 은 다른 방법을 찾습니다.