다음을 통해 디렉터리의 파일을 재귀적으로 쉽게 반복할 수 있습니다.
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
대신 find를 사용할 수 있으며 -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=