find
특별한 성공 사례를 찾지 않는 것으로 간주합니다 (오류가 발생하지 않음). 파일이 일부 find
기준 과 일치하는지 테스트하는 일반적인 방법 은 출력 find
이 비어 있는지 테스트하는 것 입니다. 일치하는 파일이있을 때 효율성 -quit
을 높이려면 GNU find에서 파일을 처음 일치시킬 때 종료하거나 다른 시스템 에서는 head
( head -c 1
가능한 경우 head -n 1
표준 인 경우) 종료하여 긴 출력을 생성하지 않고 끊어진 파이프로 죽게하십시오.
while IFS= read -r name; do
[ -n "$(find . -name "$name" -print | head -n 1)" ] || printf '%s\n' "$name"
done <file_list
bash ≥4 또는 zsh에서는 find
간단한 이름 일치를 위해 외부 명령이 필요하지 않습니다 .을 사용할 수 있습니다 **/$name
. 배쉬 버전 :
shopt -s nullglob
while IFS= read -r name; do
set -- **/"$name"
[ $# -ge 1 ] || printf '%s\n' "$name"
done <file_list
비슷한 원리의 Zsh 버전 :
while IFS= read -r name; do
set -- **/"$name"(N)
[ $# -ge 1 ] || print -- "$name"
done <file_list
또는 패턴과 일치하는 파일의 존재를 테스트하는 더 짧지 만 더 비밀스러운 방법이 있습니다. glob 한정자 N
는 일치하는 항목이 없으면 출력을 비우고 [1]
첫 번째 일치 항목 만 유지 하며 일치하는 파일 이름 대신 e:REPLY=true:
확장되도록 각 일치 항목을 변경합니다 1
. 따라서 일치하는 항목이 있거나 **/"$name"(Ne:REPLY=true:[1]) false
확장 된 항목이 true false
없는 경우로 확장됩니다 false
.
while IFS= read -r name; do
**/"$name"(Ne:REPLY=true:[1]) false || print -- "$name"
done <file_list
모든 이름을 하나의 검색으로 결합하는 것이 더 효율적입니다. 명령 행에서 시스템 길이 제한에 비해 패턴 수가 너무 많지 않은 경우 모든 이름을로 결합 -o
하고 단일 find
호출을 수행 한 후 출력을 후 처리 할 수 있습니다. 셸 메타 문자가 포함 된 이름이없는 경우 (이름도 find
패턴 임) awk를 사용하여 사후 처리하는 방법은 다음과 같습니다 (예상되지 않음).
set -o noglob; IFS='
'
set -- $(<file_list sed -e '2,$s/^/-o\
/')
set +o noglob; unset IFS
find . \( "$@" \) -print | awk -F/ '
BEGIN {while (getline <"file_list") {found[$0]=0}}
wanted[$0]==0 {found[$0]=1}
END {for (f in found) {if (found[f]==0) {print f}}}
'
또 다른 방법은 Perl 및을 사용 File::Find
하는 것입니다. 이렇게하면 디렉토리의 모든 파일에 대해 Perl 코드를 쉽게 실행할 수 있습니다.
perl -MFile::Find -l -e '
%missing = map {chomp; $_, 1} <STDIN>;
find(sub {delete $missing{$_}}, ".");
print foreach sort keys %missing'
다른 방법은 양쪽에 파일 이름 목록을 생성하고 텍스트 비교 작업을하는 것입니다. Zsh 버전 :
comm -23 <(<file_list sort) <(print -rl -- **/*(:t) | sort)
locate
.