지정된 텍스트만 포함된 파일 이름을 얻는 방법

지정된 텍스트만 포함된 파일 이름을 얻는 방법

"cat"이나 "dog" 또는 두 가지 모두에 대한 레이블이 별도의 줄에 포함된 텍스트 파일이 있는 "labels"라는 디렉토리가 있습니다.
labels 디렉터리의 파일 내용은 다음과 같습니다.

cat labels/1.txt
cat

cat labels/2.txt
dog

cat labels/3.txt
cat  
dog

"cat" 태그만 포함된 파일 이름을 얻고 싶습니다. 다음 명령을 시도했습니다.

ls labels | grep -Rwl "cat"   
labels/1.txt  
labels/3.txt  

그러나 이 명령은 "cat" 또는 둘 다를 포함하는 파일 이름을 반환합니다. 하지만 내 요구 사항은 "cat"만 포함하고 "cat"과 "dog"는 모두 포함하지 않는 파일 이름을 가져오는 것입니다.
마찬가지로 "dog"만 포함된 파일 이름을 얻으려고 할 때도 마찬가지입니다. 동일한 방식으로 검색하면 "dog" 또는 두 태그가 모두 포함된 파일 이름이 반환됩니다.

ls labels | grep -Rwl "dog"
labels/2.txt  
labels/3.txt  

답변1

두 번 사용할 수 있습니다 grep. a) 가 있는 모든 파일을 나열한 cat다음 b) dog포함된 파일을 필터링하여 제외합니다. 일치하는 파일 이름과 일치하지 않는 파일 이름을 나열하는 및 -l를 각각 사용하십시오 .-L-l-L

grep -L 'dog' $(grep -l 'cat' <list of files>)

바라보다 man grep:

-L, --file이 일치하지 않습니다.

일반 출력을 억제합니다. 대신 일반적으로 인쇄되지 않는 각 입력 파일의 이름을 인쇄합니다. 검색은 첫 번째 일치에서 중지됩니다.

-l, --일치하는 파일 포함

일반 출력을 억제합니다. 대신 print는 일반적으로 각 입력 파일의 이름을 인쇄합니다. 검색은 첫 번째 일치에서 중지됩니다.

답변2

GNU를 사용하세요 grep. xargs( -R이미 사용하고 있는 것은 어쨌든 GNU 확장입니다. 물론 GNU 확장이 더 낫습니다.)grep-r

grep -rwlZ cat labels/ | xargs -r0 grep -wL dog

최소한 하나의 cat단어를 포함하고 dog단어는 포함하지 않는 파일을 나열합니다(단어이 경우에는 "둘러싸이지 않음"을 의미합니다.단어 문자",단어 문자영숫자와 밑줄입니다). 전체 내용이 포함된 행을 검색하려면 다음 -w으로 바꾸세요 .-x cat/ dog.

답변3

"cat"은 포함하지만 "dog"은 포함하지 않는 파일 이름을 나열하려면 find및 GNU (또는 블록을 지원하는 다른 파일 (GNU 확장자이므로 블록을 지원하는 awk다른 파일 ))를 사용해 보십시오.awkENDFILEawk

$ find labels/ -type f -exec awk -v IGNORECASE=1 '
    /\<cat\>/ { cat = 1 };
    /\<dog\>/ { dog = 1 };

    ENDFILE {
      if (cat == 1 && dog == 0) {
        print FILENAME
      };
      cat = 0;
      dog = 0;
    }' {} +
labels/file1.txt

perl또는 대신 사용할 수 있습니다 awk.

$ find labels/ -type f -exec perl -l -n -e  '
    $cat = 1 if m/\bcat\b/i;
    $dog = 1 if m/\bdog\b/i;
    if (eof) {
      print $ARGV if ($cat && ! $dog);
      $cat=0;
      $dog=0;
    }' {} +
labels/file1.txt

위의 awk 및 perl 버전에 대한 출력은 labels/하위 디렉터리의 다음 파일을 사용하여 생성됩니다.

$ tail labels/*
==> labels/file1.txt <==
cat

==> labels/file2.txt <==
dog

==> labels/file3.txt <==
cat
dog

labels/file1.txt"cat"을 포함하고 "dog"를 포함하지 않는 유일한 파일이기 때문에 인쇄되는 유일한 파일 이름입니다.

답변4

for f in *; do diff -q <(sort -u "$f") <(echo cat) >/dev/null && echo "$f"; done

관련 정보