1.
첫번째:
for f in *; do
echo "$f"
done
라는 파일에 실패 -n
, -e
그리고 같은 변종 -nene
파일 이름은 백 슬래시를 포함하여, 일부 bash는 배포와 함께.
두번째:
find * -prune | while read f; do
echo "$f"
done
(라는 파일보다 경우에 실패 !
, -H
, -name
, (
... 시작이나 끝 공백이나 개행 문자가 포함 된 파일 이름)
그것은 확장하는 쉘이며 *
, find
인수로받은 파일을 인쇄하는 것 외에는 아무것도하지 않습니다. 당신은뿐만 아니라 사용할 수도 printf '%s\n'
로하는 대신 printf
내장도 피할 것입니다 너무 많은 인수를 잠재적 인 오류가 발생했습니다.
2.
의 확장 *
은 정렬되어 있으므로 정렬이 필요하지 않으면 조금 더 빨라질 수 있습니다. 에서 zsh
:
for f (*(oN)) printf '%s\n' $f
또는 간단히 :
printf '%s\n' *(oN)
bash
내가 말할 수있는 한 그에 상응하는 것이 없기 때문에에 의지해야 find
합니다.
삼.
find . ! -name . -prune ! -name '.*' -print0 |
while IFS= read -rd '' f; do
printf '%s\n' "$f"
done
(GNU / BSD -print0
비표준 확장 사용).
여전히 find 명령을 생성하고 느린 while read
루프를 사용하므로 for
파일 목록이 크지 않으면 루프를 사용하는 것보다 느릴 것 입니다.
4.
또한 쉘 와일드 카드 확장과 달리 각 파일에 대해 시스템 호출을 find
수행 lstat
하므로 정렬되지 않은 것이이를 보완하지는 않습니다.
GNU / BSD find
에서는 -maxdepth
확장을 사용하여 피할 수 있습니다 lstat
.
find . -maxdepth 1 ! -name '.*' -print0 |
while IFS= read -rd '' f; do
printf '%s\n' "$f"
done
find
stdio 출력 버퍼링을 제외하고 파일 이름을 찾 자마자 출력 하기 시작하므로 루프에서 수행하는 작업에 시간이 많이 걸리고 파일 이름 목록이 stdio 버퍼 이상인 경우 더 빠를 수 있습니다 (4 / 8 kB). 이 경우 루프 내 처리 find
가 모든 파일 찾기를 마치기 전에 시작됩니다 . GNU 및 FreeBSD 시스템에서는 stdbuf
더 빨리 발생 하도록 사용할 수 있습니다 (stdio 버퍼링 사용 안함).
5.
각 파일에 대해 명령을 실행하는 POSIX / standard / portable 방법 find
은 -exec
술어 를 사용하는 것입니다 .
find . ! -name . -prune ! -name '.*' -exec some-cmd {} ';'
그러나 echo
쉘에는 내장 버전이 echo
있지만 find
새로운 프로세스를 생성하고 /bin/echo
각 파일마다 실행해야 하므로 쉘에서 루핑을 수행하는 것보다 덜 효율적 입니다.
여러 명령을 실행해야하는 경우 다음을 수행 할 수 있습니다.
find . ! -name . -prune ! -name '.*' -exec cmd1 {} ';' -exec cmd2 {} ';'
그러나 성공한 cmd2
경우에만 실행됩니다 cmd1
.
6.
각 파일에 대해 복잡한 명령을 실행하는 정식 방법은 다음을 사용하여 쉘을 호출하는 것입니다 -exec ... {} +
.
find . ! -name . -prune ! -name '.*' -exec sh -c '
for f do
cmd1 "$f"
cmd2 "$f"
done' sh {} +
그 시간, 우리 효율적인있는 방법입니다 다시 echo
우리가 사용하고 이후 sh
의 내장의 하나는 -exec +
몇 가지로 버전 급부상 sh
가능합니다.
7.
에서 200.000 파일과 디렉토리에 내 테스트 에서 ext4에 짧은 이름의 zsh
하나 (제 2)가 첫 번째 간단한에 이어, 지금까지 가장 빠른 것입니다 for i in *
루프 (평소와 같이, 비록 bash
많은 느린 다른 조개에 비해 그입니다).
find
찾은 파일을 열지 않습니다. 많은 파일과 관련하여 여기서 당신을 물고 볼 수있는 유일한 것은 ARG_MAX 입니다.