grep을 사용하여 파일 이름을 인쇄하면 find -exec가 발생합니다.

grep을 사용하여 파일 이름을 인쇄하면 find -exec가 발생합니다.

foofind를 통해 찾은 모든 결과에 대해 실행하고 싶은 프로그램이 있습니다 . 그래서 이렇게 :

find . -name '*.o' -type f -exec foo {} \;

foo특정 문자열 막대에 대한 모든 호출의 출력을 파악하고 싶습니다. 그래서 나는 이것을 추가합니다:

find . -name '*.o' -type f -exec foo {} \; | grep bar

하지만 일치 항목이 어떤 파일에서 왔는지에 대한 원본 정보를 잃어버렸습니다. 명령 -fprintf /dev/stderr '%p\n'에 추가를 시도했지만 이제 grep 결과가 인쇄되지 않아 stdout이 사라지는 것처럼 보입니다.find

각 파일 이름을 출력에 인쇄한 다음 해당 파일에 해당하는 grep 결과를 인쇄하려면 어떻게 해야 합니까?

-H또는 인수를 작동 시키는 방법이 있으면 grep좋을 것 같지만 작성된 대로 표준 입력에서 텍스트를 전달하고 grep파일 이름을 모르기 때문에 작동하지 않습니다. 나는 다양한 주문을 시도했지만 xargs아무것도 효과가 없었습니다.

답변1

각 파일 이름을 출력에 인쇄한 다음 해당 파일에 해당하는 grep 결과를 인쇄하려면 -exec foo {} | grep파이프를 셸에 래핑하면 됩니다.

find . -name '*.o' -type f -print -exec sh -c 'foo "$1" | grep "bar"' sh {} \;

-Hgrep의 인수가 표준 입력과 함께 작동 하도록 하려면 버전이 옵션을 grep지원 하는 경우 수행할 수 있습니다.--label=

find . -name '*.o' -type f -exec sh -c '
  foo "$1" | grep -H --label="$1" "bar"
' sh {} \;

또는(검색이 +다중 매개변수 대체를 지원하는 경우 \;):

find . -name '*.o' -type f -exec sh -c '
  for f; do foo "$f" | grep -H --label="$f" "bar"; done
' sh {} +

답변2

각 파일 이름을 출력에 인쇄한 다음 해당 파일에 해당하는 grep 결과를 인쇄하려면 어떻게 해야 합니까?

1.)두 개의 grep 인스턴스를 사용합니다. 하나는 파일 이름을 인쇄하고 다른 하나는 일치 항목을 인쇄합니다.

find . -name '*.o' -type f -exec grep -l bar {} \; -exec grep bar {} \;

2.)grep이 여러 파일인 것처럼 동작하도록 합니다.

find . -name '*.o' -type f -exec grep bar {} /dev/null \;

[..]-exec foo {} \;[...]예제에서 볼 수 있듯이 파이프라인 내에서 grep을 실행하는 문제는 해결되지 않습니다 .

답변3

이것은 보기 흉하지만 다음과 같이 하면 도움이 될 것입니다.

find . -name '*.o' -type f -exec sh -c 'foo "$1" | sed "s@^@$1\t@"' _ {} \;

이렇게 하면 각 줄의 시작 부분에 파일 이름과 탭 문자가 배치됩니다. 기본 밑줄은 $0결과 쉘에 채워지는 문자열이며 파일 이름은 그대로 유지됩니다 $1. 이제 find 출력을 grep할 수 있으며 파일 이름이 출력에 나타납니다.


이는 해당 문자가 포함된 파일 이름에 대해 중단됩니다 @. 이것이 문제라면 쉘 스크립트를 향상시킬 수 있습니다:

find . -name '*.o' -type f -exec sh -c '
    r=$(echo "$1" | sed "s/@/\\\\\\\\@/g")
    foo "$1" | sed "s@^@$r\t@"
' _ {} \;

8개의 백슬래시는 시행착오를 통해 결정되었습니다...

또는 편리한 "검색 및 바꾸기" 매개변수 대체 기능이 있는 bash(또는 ksh)를 사용하세요.

find . -name '*.o' -type f -exec ksh -c 'foo "$1" | sed "s@^@${1//@/\\\\@}\t@"' _ {} \;

관련 정보