소스 트리에서 내용별로 파일을 재귀적으로 찾고 싶습니다. 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개의 문자열이 포함된 줄에만 해당됩니다.