foo
find를 통해 찾은 모든 결과에 대해 실행하고 싶은 프로그램이 있습니다 . 그래서 이렇게 :
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 {} \;
-H
grep의 인수가 표준 입력과 함께 작동 하도록 하려면 버전이 옵션을 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@"' _ {} \;