저는 (2T 드라이브에 있는 약 900,000개의 파일 중에서) 관련 없는 파일을 찾아 식별해야 한다는 사실을 깨달았습니다. 보관하고 싶은 파일이 많이 있으며 이러한 양호한 것으로 알려진 파일에 대한 파일 이름 패턴이 있습니다. 내가 원하는 것은 어떤 패턴과도 일치하지 않는 파일을 찾는 것입니다.
파일 이름 패턴 목록과 일치하지 않는 파일을 찾는 방법은 무엇입니까?
실행하여 find
모든 파일 목록을 얻을 수 있고 grep -v
그 결과를 파일에 저장된 패턴 목록과 함께 사용할 수 있습니다. 이것이 표준적인 방법입니까, 아니면 이러한 부적합 파일을 찾을 수 있는 깔끔한 방법이 있습니까?
설명 - 답변을 바탕으로 추가 정보를 제공합니다. 나는 많은 수의 패턴(20개 이상, 아마도 100개 이상)을 가질 것으로 예상하고, 이를 파일에 저장하고 싶고, 물론 새 패턴을 추가하는 쉬운 방법을 원합니다. 많은 조회 매개변수를 직접(깨지기 쉬움) 편집하는 것을 피하고 싶지만 목록을 작성하면 효과가 있을 수 있습니다.
답변1
find(1)
귀하의 요구를 충족시킬 만큼 강력합니다. 괄호를 사용하여 일치하는 모든 이름을 표현식으로 수집하고 이를 부정하여 표시하면 됩니다.부적격파일 이름. 예를 들어 모든 파일을 표시합니다.아니요이름이 *.txt
, *.bz2
또는 *.zip
:
$ find . \! \( -name \*.txt -o -name \*.bz2 -o -name \*.zip \)
대신 GNU와 BSD를 사용할 수 있습니다 -not
. POSIX와 호환되지 않지만 쉘이 이를 해석하지 못하도록 이스케이프할 필요는 없습니다.\!
find
파일의 패턴을 기반으로 표현식을 작성하려면 쉘 스크립트를 작성하십시오.
#!/bin/sh
set --
while IFS= read -r pattern
do
set -- "$@" -o "$pattern"
done < .fnpatterns
if [ $# -ne 0 ]; then
shift
set -- -not \( "$@" \)
fi
find . "$@"
이를 위해서는 현재 디렉터리에 .fnpatterns
한 줄에 하나의 패턴을 호출하는 파일이 필요합니다. 위의 줄을 모방하려면 다음을 포함해야 합니다.
*.txt
*.bz2
*.zip
쉘 스크립트는 *
패턴의 문자를 이스케이프 처리합니다.
원하는 만큼 복잡하게 만들 수 있습니다. 몇 가지 생각:
디렉터리가 아닌 일반 파일만 표시하도록 명령
-type f
에 추가되었습니다 .find
고정된 위치에 있을 것으로 예상하는 대신 스키마 파일 이름을 인수로 전달합니다.
스키마 파일을 원래 위치에 그대로 두고
-o -name .fnpatterns
빌드find
명령에 추가하면 출력에 표시되지 않습니다. (이는 또한 해커가 빌드 표현식의 리드를shift
"먹는" 것을 방지합니다.)-o
find
또는 유사한 명령을 통해 명령에 작업을 추가합니다-exec
.스키마 파일에 빈 줄이나 주석을 허용합니다.
답변2
Perl을 언급하신 이후로 ...
#!/usr/bin/perl
use strict;
use warnings;
use File::Find qw{find};
my %patterns;
while (<>) {
chomp;
$patterns{$_}++;
}
die "No pattern supplied\n" unless keys %patterns;
find(
sub{
my $matches_a_pattern=0;
for my $pattern (keys %patterns){
my $glob_pattern = $pattern;
for($glob_pattern){
s/\./\\./g;
s/\*/.*/g;
s/\?/./g;
}
$matches_a_pattern++ if ( /\Q$pattern\E/ or /$glob_pattern/);
}
print "$File::Find::name\n" unless $matches_a_pattern;
}
, '.' )
이것을 다음과 같이 부르십시오.
/path/to/my/script file_with_patterns
끝에 있는 것을 .
걷고 싶은 나무 꼭대기로 바꾸세요.