"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 grep
및 xargs
( -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
다른 이름 )를 사용하여 다음과 같이 시도해 보십시오.awk
ENDFILE
awk
$ 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