GNU 도구로 :
find . -type f -exec grep -lZ FIND {} + | xargs -r0 grep -l ME
당신은 표준 적으로 할 수 있습니다 :
find . -type f -exec grep -q FIND {} \; -exec grep -l ME {} \;
그러나 그것은 파일 당 두 개의 grep을 실행합니다. grep파일 이름에 문자를 허용하면서 많은 수 의 실행을 피하고 이식성을 유지하려면 다음을 수행하십시오.
convert_to_xargs() {
sed "s/[[:blank:]\"\']/\\\\&/g" | awk '
{
if (NR > 1) {
printf "%s", line
if (!index($0, "//")) printf "\\"
print ""
}
line = $0
}'
END { print line }'
}
find .//. -type f |
convert_to_xargs |
xargs grep -l FIND |
convert_to_xargs |
xargs grep -l ME
작은 따옴표, 큰 따옴표 및 백 슬래시로 구분할 수있는 단어 목록 find을 xargs (공백 (SPC / TAB / NL 및 일부 구현이있는 로케일의 다른 공란이 예상 됨)가 예상 됨)에 적합한 형식으로 출력을 변환하는 아이디어 xargs공백과 서로 탈출).
일반적으로 find -print파일 이름을 줄 바꿈 문자로 분리하고 파일 이름에서 찾은 줄 바꿈 문자를 이스케이프하지 않기 때문에 의 출력을 후 처리 할 수 없습니다 . 예를 들면 다음과 같습니다.
./a
./b
우리는 그것이라는 하나 개의 파일인지 알 수있는 방법이 없어 한 b라는 디렉토리를 a<NL>.하거나이 두 파일을인지 a하고 b.
사용하여 .//.있기 때문에, //캔에 의해 출력으로 파일 경로 그렇지 않으면 나타나지 않습니다 find(이 빈 이름을 가진 디렉토리 같은 것은 없습니다하기 때문에 /파일 이름에 사용할 수 없습니다), 우리가 알고있는 우리는이 포함 된 라인을 보면 //다음의 것을, 새 파일 이름의 첫 번째 줄 따라서이 awk명령을 사용 하여 줄 바꿈 문자를 제외한 모든 줄 바꿈 문자를 이스케이프 할 수 있습니다 .
위의 예 find를 보면 첫 번째 경우 (한 파일)로 출력됩니다.
.//a
./b
어느 awk가 탈출합니까?
.//a\
./b
그래서 xargs그것은 그것을 하나의 논쟁으로 간주합니다. 두 번째 경우 (파일 두 개) :
.//a
.//b
어느 awk것이 그대로 xargs남았는지 두 가지 주장이 있습니다.