콘텐츠별로 재귀적으로 파일 찾기

콘텐츠별로 재귀적으로 파일 찾기

소스 트리에서 내용별로 파일을 재귀적으로 찾고 싶습니다. grep을 사용하여 다음을 시도했습니다.

$ grep -rn printf | grep %s | grep bcm_errmsg\(rv\)

이렇게 하면 내가 원하는 대로 각 행이 반환되지만 이제는 일치하는 각 파일의 파일 이름을 가져오고 싶기 때문에 다음과 같이 변경했습니다.

$ grep -rn printf | grep %s | grep -l bcm_errmsg\(rv\)

하지만 파일 이름을 인쇄하는 대신

(standard input)

표준 출력으로 인쇄합니다. 각 파일 이름과 경로( sed사용할) 를 얻으려면 이 문제를 어떻게 해결해야 합니까 ?

내가 하고 싶은 일: printf다음 줄이 포함된 모든 파일을 찾은 %s다음 bcm_errmsg(rv)찾은 파일에 다음 sed 명령을 적용합니다.

sed -i 's/%s/%d/g; s/bcm_errmsg(rv)/rv/g;'

답변1

내 생각엔 당신이 일을 너무 복잡하게 생각하는 것 같아요. foo현재 디렉터리와 하위 디렉터리의 모든 파일에서 문자열을 찾으 려면 다음을 실행하세요.

grep -r "foo" *

기본적으로 grep은 발견된 파일 이름 앞에 일치하는 줄을 출력합니다.

다음은 일치하는 줄이 아닌 파일 이름만 출력합니다.

grep -rl "foo" *

답변2

@steeldriver의 원래 아이디어에 따라 다음과 같이 할 수 있습니다.

egrep -rl '.*printf.*%s.*bcm_errmsg\(rv\).*' . | xargs -d '\n' sed -i '/printf/ s/%s/%d/; /printf/ s/bcm_errmsg(rv)/rv/'

답변3

grep -rlZP '(?=.*printf)(?=.*%s)(?=.*bcm_errstr\(rv\))' . |
xargs -r0 sed -i -e '
        /%s/!b
        /printf/!b
        /bcm_errstr(rv)/!b
        s/%s/%d/g;s/bcm_errstr(rv)/rv/g
'

먼저 재귀 디렉터리를 실행합니다. 같은 줄에 있는 printf, %s 및 bcm_errstr(rv) 문자열을 사용하여 현재 디렉터리에서 파일을 스캔하지만 순서는 가능합니다. grep이를 수행하는 데 도움이 되는 옵션은 다음과 같습니다.

  • -r=> 현재 디렉토리와 그 아래의 모든 파일을 재귀적으로 시작합니다.
  • -l=>는 기준과 일치하는 파일 이름을 나열합니다(예: 같은 줄에 있는 3개의 문자열 모두).
  • -Z=> 선택한 파일 이름은 일반적인 줄 바꿈(\n) 대신 공백으로 구분된(\0) 형식이므로 모든 유형의 파일 이름을 처리할 수 있습니다.
  • -P=> Perl 정규식 엔진을 활성화하여 미리보기를 사용하여 3개의 문자열이 같은 줄에 있는지 확인할 수 있습니다.

파이프의 다른 쪽 끝에는 xargs\0으로 구분된 파일 이름이 수신 대기 중입니다. 그런 다음 가능한 한 많은 파일 이름을 sed 명령줄에 제공합니다. 이전 질문에서 subs를 실행하는 sed 명령을 이미 알고 계십니다. 같은 줄에 3개의 문자열이 포함된 줄에만 해당됩니다.

관련 정보