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

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

"cat" 또는 "dog" 또는 두 가지 모두를 별도의 줄에 포함하는 텍스트 파일이 있는 "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"과 "dog"가 아닌 "cat"만 포함하는 파일 이름을 얻는 것입니다.
마찬가지로 "개"만 포함된 파일의 이름을 얻으려고 할 때도 마찬가지입니다. 동일한 방식으로 검색하면 "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, --files-without-match

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

-l, --files-with-matches

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

답변2

GNU grepxargs( -R이미 사용하고 있는 것은 grep어쨌든 GNU 확장이지만 -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

관련 정보