
내 소스 트리에서 내용별로 파일을 반복적으로 찾고 싶습니다. grep을 사용하여 다음을 시도했습니다.
$ grep -rn printf | grep %s | grep bcm_errmsg\(rv\)
이렇게 하면 내가 원하는 대로 모든 줄이 반환되지만 이제는 일치하는 각 파일의 파일 이름을 가져오고 싶기 때문에 다음과 같이 변경했습니다.
$ grep -rn printf | grep %s | grep -l bcm_errmsg\(rv\)
하지만 파일 이름을 인쇄하는 대신
(standard input)
stdout으로 인쇄됩니다. 각 파일 이름 및 경로( 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)가 아닌 null로 구분되어 있으므로(\0) 모든 종류의 파일 이름을 처리할 수 있습니다.-P
=> Perl 정규식 엔진을 활성화하면 미리보기를 사용하여 3개의 문자열이 같은 줄에 존재하는지 확인할 수 있습니다.
파이프 반대편에서는 xargs
\0으로 구분된 파일 이름을 받기를 기다리고 있습니다. 그런 다음 가능한 한 모든 파일 이름을 sed 명령줄에 제공합니다. 이전 질문에서 이미 알고 있는 sed 명령으로 하위 작업을 수행합니다. 같은 줄에 3개의 문자열이 포함된 줄에서만 가능합니다.