해당 단어가 포함된 모든 파일 foo
과 해당 단어가 포함된 파일을 찾으려면 bar
다음을 사용할 수 있습니다.
grep -Ilri foo . | xargs grep -i bar
(대소문자를 구분하지 않고 바이너리 파일을 제외합니다.)... 그러나 파일 경로가 다음과 같은 경우
/Users/myusername/Text Files
그러면 작동하지 않습니다. 왜냐하면 이제 xargs
부품이
grep -i bar /Users/myusername/Text Files
하지만 실제로는 그럴 필요가 있다
grep -i bar "/Users/myusername/Text Files"
또는
grep -i bar /Users/myusername/Text\ Files
어떻게 작동하게 만들까요? (macOS Monterey에서).
답변1
grep
널 바이트로 파일 이름을 구분하는 GNU의 -Z
/ 옵션을 지원하고 --null
(FreeBSD는 긴 --null
변형만 지원) xargs
널 바이트를 입력 구분 기호로 사용하는 옵션 -0
(일부 있음)을 지원하는 경우 이를 사용하여 파일 이름을 --null
안전하게 처리할 수 있습니다.
grep -Ilri --null foo . | xargs -0 grep -i bar
grep
및 가 xargs
이러한 비표준 옵션을 지원하지 않는 경우 (하지만 둘 다 표준 -r
이 아님 -I
) 다음을 사용할 수 있습니다 find
.
find . -type f -exec grep -Iiq foo {} \; -exec grep -iq bar {} \; -print
현재 디렉터리에서 시작하는 파일을 찾고, 찾은 각 파일에 대해 grep
"foo"가 포함되어 있는지 확인하기 위해 실행되고, 그렇다면 grep
"bar"가 포함되어 있는지 확인하기 위해 다시 실행되고, 포함되어 있으면 인쇄합니다. 그것의 이름.
이는 매우 효율적이지는 않지만 안전하게 작동합니다.
답변2
foo
Unix 시스템에서 POSIX 도구를 강제로 "해당 단어 와 그 안에 있는 단어가 포함된 모든 파일을 찾도록 "하려면(테스트되지 않음):bar
find . -type f -exec \
awk '
FNR==1 { x=y=0 }
{ $0 = tolower($0) }
/foo/ { x=1 }
/bar/ { y=1 }
x && y { hits[FILENAME]; nextfile }
END { for (fname in hits) print fname }
' {} +
또는 원하는 경우:
find . -type f -exec \
awk '
FNR==1 { x=y=0 }
{ $0 = tolower($0) }
/foo/ { x=1 }
/bar/ { y=1 }
x && y && !seen[FILENAME]++ { print FILENAME; nextfile }
' {} +
위의 두 경우 모두 효율성을 위해 이를 지원하는 awk를 사용 nextfile
하지만, 지원하지 않는 awk에서도 동일한 파일 이름을 여러 번 인쇄하지 않도록 코드를 작성합니다.
위의 내용은 하위 문자열이나 정규식 대 문자열 일치에 관심이 없다고 가정합니다.