
디렉터리의 파일을 반복적으로 반복하는 작업은 다음과 같이 쉽게 수행할 수 있습니다.
find . -type f -exec bar {} \;
그러나 위의 방법은 많은 조건부 분기, 루핑 등을 수행해야 하는 더 복잡한 작업에는 작동하지 않습니다. 나는 이것을 위와 같은 용도로 사용했습니다.
while read line; do [...]; done < <(find . -type f)
그러나 이것은 모호한 문자가 포함된 파일에서는 작동하지 않는 것 같습니다.
$ touch $'a\nb'
$ find . -type f
./a?b
이렇게 모호한 문자를 잘 처리할 수 있는 대안이 있을까요?
답변1
또 다른 용도안전한find
:
while IFS= read -r -d '' -u 9
do
[Do something with "$REPLY"]
done 9< <( find . -type f -exec printf '%s\0' {} + )
(이것은 모든 POSIX에서 작동 find
하지만 쉘 부분에는 bash가 필요합니다. *BSD 및 GNU find를 사용하면 -print0
대신 사용할 수 -exec printf '%s\0' {} +
있으며 약간 더 빠릅니다.)
이를 통해 루프 내에서 표준 입력을 사용할 수 있으며 다음과 같이 작동합니다.어느길.
답변2
이를 수행하는 방법은 다음과 같이 간단합니다.
find -exec sh -c 'inline script "$0"' {} \;
또는...
find -exec executable_script {} \;
답변3
가장 간단하면서도 안전한 접근 방식은 쉘 글로빙을 사용하는 것입니다.
$ for f in *; do printf ":%s:\n" "$f"; done
:a b:
:c
d:
:-e:
:e f:
h:
위의 내용을 (bash의) 하위 디렉터리로 반복하려면 globstar
옵션을 사용할 수 있습니다. 또한 dotglob
이름이 다음으로 시작하는 파일과 일치하도록 설정됩니다 .
.
$ shopt -s globstar dotglob
$ for f in **/*; do printf ":%s:\n" "$f"; done
:a b:
:c
d:
:-e:
:e f:
:foo:
:foo/file1:
:foo/file two:
h:
bash 4.2까지는 **/
디렉토리에 대한 심볼릭 링크로 반복된다는 점에 유의하세요. bash 4.3 부터는 **/
.find
또 다른 일반적인 솔루션은 다음 find -print0
과 함께 사용하는 것입니다 xargs -0
.
$ touch -- 'a b' $'c\nd' $'e\tf' $'g\rh' '-e'
$ find . -type f -print0 | xargs -0 -I{} printf ":%s:\n" {}
h:/g
:./e f:
:./a b:
:./-e:
:./c
d:
h:/g
파일 이름 에 \r
.
답변4
읽기 루프를 이식적으로 수행하는 것은 약간 어렵지만 특히 bash의 경우 다음과 같은 것을 시도해 볼 수 있습니다.이것.
관련 부분:
while IFS= read -d $'\0' -r file ; do
printf 'File found: %s\n' "$file"
done < <(find . -iname 'foo*' -print0)
이는 find
NUL 문자(0x00)로 구분된 출력을 인쇄하고 백슬래시를 다른 문자에 대한 이스케이프( )로 처리하지 않고 read
NUL로 구분된 줄( )을 가져오며 줄에서 단어 분할( )을 수행하지 않도록 지시합니다. 0x00은 Unix의 파일 이름이나 경로에 나타날 수 없는 바이트이므로 모든 이상한 파일 이름 문제를 처리해야 합니다.-d $'\0'
-r
IFS=