grep과 일치하는 모든 파일에서 문자열을 검색하고 바꾸려고합니다.
grep -n 'foo' *
다음과 같은 형식으로 출력을 제공합니다.
[filename]:[line number]:[text]
그렙에 의해 반환 된 각 파일에 대해, 나는 대체하여 파일을 수정하고 싶습니다 foo
와 함께 bar
.
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
박 확장자를 가진 원본 파일의 사본을 만들어 (그것은 어떤 확장 당신처럼 될 수 있습니다)와 g
sed의 식의 말은 여러 복사본을 대체하기 위해 sed를 알려줍니다 한 줄 (첫 번째 줄만 아님). -print
찾을 파일이 일치되고 있었다 쇼에 편리합니다. 이 모든 것은 시스템에있는 이러한 도구의 정확한 버전에 따라 다릅니다.
find
시작할 디렉토리 (예 : find . -name '*.html'
또는) 를 명령 에 제공해야합니다 find directoryname/ -name '*'
.
sed -ie 's/foo/bar/g' *
옵션 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/' *
for i in *; do ...
sed는 파일 목록을 인수로 사용할 수 있습니다.
for i in *; do; sed -i 's/foo/bar/g' "$i"; done
이것은 perl을 사용하거나 찾을 필요없이 grep을 사용하여 작동합니다.
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
-i
다른 OS에서 작동 하지 않는다는 것을 몰랐습니다. 우분투에서 나를 위해 작동합니다.
xargs
맨 페이지 (Ubuntu의) -i
는 더 이상 사용되지 않으며 -I
대신 사용 한다고 말합니다 . 그래서, 우리는 말해야한다 :grep -rli 'old-word' * | xargs -I filepath sed -i 's/old-word/new-word/g' filepath
find . -type f -print0 | xargs -0 <sed/perl/ruby cmd>
한 번에 하나의 인터프리터를로드하여 여러 공간에 포함 된 파일 이름을 처리합니다. 훨씬 더 빨리.
이미 find 및 sed 사용에 대한 대답
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입니다 . 까다로운 이름 변경 및 리팩토링 작업. 선호하는 이유는 다음과 같습니다.
이것은 실제로 보이는 것보다 쉽습니다.
grep -Rl 'foo' ./ | xargs -n 1 -I % sh -c "ls %; sed -i 's/foo/bar/g' %";
쉬워요. find, grep, xargs, sed 및 awk에 대해 잘 알고 있다면 bash에서 텍스트 파일을 조작 할 때 거의 불가능한 것이 없습니다. :)
Can't open Untitled: No such file or directory, <> line 5
"Untitled Folder / file.txt"를 시도 할 때.