[linux] 명령 줄 : grep과 일치하는 모든 파일 이름에서 검색 및 바꾸기

grep과 일치하는 모든 파일에서 문자열을 검색하고 바꾸려고합니다.

grep -n 'foo' * 다음과 같은 형식으로 출력을 제공합니다.

[filename]:[line number]:[text]

그렙에 의해 반환 된 각 파일에 대해, 나는 대체하여 파일을 수정하고 싶습니다 foo와 함께 bar.



답변

grep과 일치하는 모든 파일에서 문자열을 검색하고 바꾸는 것을 의미합니까?

perl -p -i -e 's/oldstring/newstring/g' `grep -ril searchpattern *`

편집하다

이것은 상당히 인기있는 질문 인 것 같아서 업데이트 할 것이라고 생각했습니다.

요즘은 ack-grep사용자 친화적이기 때문에 주로 사용 합니다. 따라서 위의 명령은 다음과 같습니다.

perl -p -i -e 's/old/new/g' `ack -l searchpattern`

파일 이름의 공백을 처리하려면 다음을 실행할 수 있습니다.

ack --print0 -l searchpattern | xargs -0 perl -p -i -e 's/old/new/g'

당신은 ack-grep. 검색을 HTML 파일로만 제한하려는 경우 :

ack --print0 --html -l searchpattern | xargs -0 perl -p -i -e 's/old/new/g'

공백이 문제가되지 않는다면 더 짧습니다.

perl -p -i -e 's/old/new/g' `ack -l --html searchpattern`
perl -p -i -e 's/old/new/g' `ack -f --html` # will match all html files


답변

당신이 준 예에 따르면 이것은 당신이 원하는 것 같습니다.

sed -i 's/foo/bar/g' *

재귀 적이 지 않습니다 (하위 디렉토리로 내려 가지 않음). 트리 전체에서 선택한 파일을 대체하는 멋진 솔루션을 위해 find를 사용합니다.

find . -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;

(가) *.html파일이 일치해야하는 표현의 .bak애프터이 -i박 확장자를 가진 원본 파일의 사본을 만들어 (그것은 어떤 확장 당신처럼 될 수 있습니다)와 gsed의 식의 말은 여러 복사본을 대체하기 위해 sed를 알려줍니다 한 줄 (첫 번째 줄만 아님). -print찾을 파일이 일치되고 있었다 쇼에 편리합니다. 이 모든 것은 시스템에있는 이러한 도구의 정확한 버전에 따라 다릅니다.


답변

옵션 sed(1)이 있으면 -i다음과 같이 사용하십시오.

for i in *; do
  sed -i 's/foo/bar/' $i
done

그렇지 않은 경우 사용하려는 언어에 따라 다음과 같은 여러 가지 방법이 있습니다.

ruby -i.bak -pe 'sub(%r{foo}, 'bar')' *
perl -pi.bak -e 's/foo/bar/' *


답변

위의 솔루션 또는 시스템 전체 검색을 좋아하고 사용했으며 수천 개의 파일 중에서 교체했습니다.

find -name '*.htm?' -print -exec sed -i.bak 's/foo/bar/g' {} \;

나는 ‘* .htm?’으로 가정한다. .html 대신 .htm 및 .html 파일을 모두 검색하고 찾습니다.

백업 파일을 더 쉽게 정리하기 위해 .bak를 시스템 전체에서 사용되는 물결표 (~)로 대체합니다.


답변

이것은 perl을 사용하거나 찾을 필요없이 grep을 사용하여 작동합니다.

grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @


답변

find . -type f -print0 | xargs -0 <sed/perl/ruby cmd>한 번에 하나의 인터프리터를로드하여 여러 공간에 포함 된 파일 이름을 처리합니다. 훨씬 더 빨리.


답변

이미 findsed 사용에 대한 대답

find -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;

아마도 표준 답일 것입니다. 또는 명령 perl -pi -e s/foo/bar/g'대신 사용할 수 있습니다 sed.

대부분의 빠른 사용을 위해 rpl 명령 이 기억하기 더 쉽다는 것을 알 수 있습니다. 다음은 현재 디렉토리의 모든 파일에서 재귀 적으로 대체 (foo-> bar)입니다.

rpl -R foo bar .

대부분의 Linux 배포판에서는 기본적으로 사용할 수 없지만 설치가 빠릅니다 ( apt-get install rpl또는 유사).

그러나 정규 표현식과 역 대체 또는 파일 이름 바꾸기와 검색 및 바꾸기를 포함하는 더 힘든 작업의 ​​경우 내가 아는 가장 일반적이고 강력한 도구는 repren입니다 . 까다로운 이름 변경 및 리팩토링 작업. 선호하는 이유는 다음과 같습니다.

  • 파일 이름 변경 및 파일 내용 검색 및 바꾸기 (디렉토리 간 파일 이동 및 새 상위 디렉토리 생성 포함)를 지원합니다.
  • 검색 및 바꾸기를 수행하기 전에 변경 사항을 확인하십시오.
  • 역 치환, 전체 단어, 대소 문자 구분 및 대소 문자 보존 (foo-> bar, Foo-> Bar, FOO-> BAR 대체) 모드로 정규 표현식을 지원합니다.
  • 스왑 (foo-> bar 및 bar-> foo) 또는 고유하지 않은 대체 세트 (foo-> bar, f-> x)를 포함한 여러 대체와 함께 작동합니다.

예제 는 README확인하십시오 .