awk 또는 sed로 문자열을 재귀 적으로 찾거나 바꾸는 방법은 무엇입니까?


675

발생하는 모든 항목을 찾아서 바꾸려면 어떻게합니까?

subdomainA.example.com

subdomainB.example.com

/home/www/디렉토리 트리 아래의 모든 텍스트 파일에서 재귀 적으로?


93
팁 : svn 체크 아웃 트리에서 아래 작업을 수행하지 마십시오. 매직 .svn 폴더 파일을 덮어 씁니다.
J. Polfer

7
맙소사, 이것이 바로 방금 한 일입니다. 그러나 그것은 효과가 있었고 아무런 해를 끼치 지 않은 것 같습니다. 일어날 수있는 최악의 상황은 무엇입니까?
J. Katzwinkel

5
@ J.Katzwinkel : 최소한 체크섬이 손상되어 저장소가 손상 될 수 있습니다.
ninjagecko

3
sed를 사용하는 모든 사람들을위한 빠른 팁 : 파일에 후행 줄 바꿈을 추가합니다. 원하지 않는 경우 먼저 일치하지 않는 찾기 바꾸기를 수행하고 git에 커밋하십시오. 그런 다음 실제 작업을 수행하십시오. 그런 다음 대화식으로 리베이스하고 첫 번째 것을 삭제하십시오.
funroll 2009 년

5
xargs로 파이프하기 전에 -path ./.git -prune -oin 을 사용하여 결과에서 git과 같은 디렉토리를 제외 할 수 있습니다find . -path ./.git -prune -o -type f -name '*matchThisText*' -print0
devinbost

답변:


850
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'

-print0find줄 바꿈이 아닌 널 문자로 구분 된 각 결과를 인쇄하도록 지시 합니다. 디렉토리에 이름에 줄 바꿈이있는 파일이있는 경우에도 xargs올바른 파일 이름으로 작업 할 수 있습니다 .

\( -type d -name .git -prune \)는이라는 모든 디렉토리를 완전히 건너 뛰는 표현식입니다 .git. SVN을 사용하거나 보존하려는 다른 폴더가 있으면 쉽게 확장 할 수 있습니다. 더 많은 이름과 일치하면됩니다. -not -path .git디렉토리의 모든 파일을 검사하는 대신 파일을 완전히 건너 뛰기 때문에 대략적으로 이지만 더 효율적입니다. -o그 후에 때문에 방법의 필요 -prune실제로 작동합니다.

자세한 내용은를 참조하십시오 man find.


132
OSX에서 sed: 1: "...": invalid command code .문제 가 발생할 수 있습니다. -i 옵션은 확장을 기대하고 's/../...'명령을 구문 분석하는 것으로 보입니다 . 해결 방법 : 확장명 ''을 -i 옵션과 같이 전달하십시오 sed -i '' 's/....
Robert Lujo

6
참고 : 디렉토리에서 이것을 사용하고 왜 svn st변경 사항이 표시되지 않는지 궁금하다면 .svn 디렉토리의 파일도 수정했기 때문입니다! find . -maxdepth 1 -type f -print0 | xargs -0 sed -i 's/toreplace/replaced/g'대신 사용하십시오 .
ACK_stoverflow

57
또한 git repo에 있다면주의하십시오. 나는 이것을 분명한 지점에서 테스트하여 현명하다고 생각하여 뭔가 나쁜 일을하면 되돌릴 수 있지만 대신 내 자식 인덱스를 손상 시켰습니다.
Ciryon

13
grep -r 'hello' -l --null . | xargs -0 sed -i 's#hello#world#g'관련없는 파일을 편집하지 않으려면 이 를 사용하십시오 (sed는 파일 인코딩을 변경할 수 있음).
caiguanhao

6
"하지만 대신 내 자식 인덱스가 손상되었습니다." 이것에 대해 너무 걱정하지 마십시오. find .git ... | ... 'sed -i s/(the opposite from before)/g'git index를 고치기 위해 할 수 있습니다
Massey101

259

참고 : git repo를 포함하는 폴더에서이 명령을 실행하지 마십시오. .git를 변경하면 git 색인이 손상 될 수 있습니다.

find /home/www/ -type f -exec \
    sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

여기의 다른 답변과 비교할 때, 이것은 대부분의 것보다 간단하고 펄 대신 sed를 사용합니다. 이는 원래 질문에서 요구 한 것입니다.


50
BSD sed (Mac OS X 포함)를 사용하는 경우 sed의 -i옵션에 명시적인 빈 문자열 인수를 제공해야합니다 . 즉 : sed -i '' 's/original/replacement/g'
Nathan Craike

2
@JohnZwinck 내 실수는 +를 놓쳤다. 이상하게도 Nikita의 솔루션은 더 빠르게 실행됩니다.
Sam

6
@AoeAoe : 생성 된 프로세스 +수를 크게 줄 sed입니다. 더 효율적입니다.
John Zwinck

4
자식 저장소가있는 폴더에서 어떻게 안전하게 할 수 있습니까?
Hatshepsut

20
검색 결과에서 repo를 제외하면 git repo가 ​​포함 된 폴더에서 실행하는 것이 안전합니다 find . -not -path '*/\.git*' -type f ....
데일 앤더슨

210

나를위한 가장 간단한 방법은

grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'

1
@Anatoly : 단 하나의 질문 : 어떻게 바이너리 파일 (실행 파일)을 제외시킬 수 있습니까?
user2284570

3
@ user2284570 -I또는 --binary-file=without-matchgrep 플래그를 사용하십시오 .
Zéychin

34
와 같이 디렉토리를 제외해야 할 때 특히 효과적입니다 .svn. 예를 들면 :grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
phyatt

11
brew install gnu-sed그리고 gsed고통의 세계를 피하기 위해 OSX에서 사용 합니다.
P i

1
여러분의 프로젝트가 git 버전이라면, 이것을 대신 사용하십시오 : git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'. 그것은 당신의 .gitdir 을 f * ck에 전혀 좋지 않다
Paolo

61

모든 트릭은 거의 동일하지만 나는 이것을 좋아합니다.

find <mydir> -type f -exec sed -i 's/<string1>/<string2>/g' {} +
  • find <mydir>: 디렉토리에서 찾아보십시오.

  • -type f:

    파일 형식 : 일반 파일

  • -exec command {} +:

    이 -exec 조치 변형은 선택된 파일에서 지정된 명령을 실행하지만 명령 행은 선택한 각 파일 이름을 끝에 추가하여 빌드됩니다. 명령의 총 호출 수는 일치하는 파일 수보다 훨씬 적습니다. 명령 행은 xargs가 명령 행을 빌드하는 것과 거의 같은 방식으로 빌드됩니다. `{} '인스턴스는 하나만 허용됩니다. 명령은 시작 디렉토리에서 실행됩니다.


-exec와 함께 @ user2284570? 도구 이름 대신 실행 파일 경로를 설정하십시오.
I159

@ I159 : 아니오 : 실행 바이너리를 제외합니다 (그러나 쉘 스크립트는 포함합니다) .
user2284570

8
@ I159이 답변은 John Zwinck 's와 동일하지 않습니까?
Reinstate Monica 제발

1
@ user2284570 "이진 파일"의 개념은 완전히 정의 된 것은 아닙니다. 이 file명령을 사용하여 각 파일 유형을 결정하려고 시도 할 수 있지만 출력의 우연한 변형이 약간 어둡게 보일 수 있습니다. -I(일명 --mime) 옵션은 어느 정도 도움이, 또는 --mime-type당신이있는 경우. 이 깔끔한 한 줄짜리 라이너를 정확하게 리팩터링하는 방법은 불행히도이 작은 주석 상자의 범위를 벗어납니다. 도움이 필요한 경우 별도의 질문을 게시 하시겠습니까? (여기에 링크가있는 코멘트를 추가하십시오.)
tripleee

1
가장 깨끗한 답변! 고맙습니다 친구
jukerok

39
cd /home/www && find . -type f -print0 |
  xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'

2
내가 사용하는 이유가 궁금 -print0하고 xargs대신 -exec-execdir?
Philipp

4
from "man find": 지정된 명령이 일치하는 각 파일마다 한 번씩 실행됩니다. 즉, / home / www에 2000 개의 파일이 있으면 'find ... -exec ...'는 2000 개의 perl 호출을 초래합니다. 반면 '찾기 ... | xargs ... '는 perl을 한두 번만 호출합니다 (ARG_MAX는 약 32K이고 평균 파일 이름 길이는 20이라고 가정).
러시아어를 고용

2
@Russian Russian : 이것이 사용하는 이유 find -exec command {} +입니다. xargs와 같은 명령을 과도하게 호출하지는 않지만 별도의 프로세스가 없습니다.
John Zwinck

2
어느 플랫폼에서? xargs 솔루션은 이식성이 뛰어나 발견 된 모든 파일에 대해 하위 프로세스를 호출하지 않는 "find ... -exec"의 "마법"호출이 아닙니다.
Russian

4
@EmployedRussian find -exec ... {} +은 2006 년부터 POSIX로 지정되었습니다.
Charles Duffy

34

나에게 가장 기억하기 쉬운 해결책은 https : //.com/a/2113224/565525입니다.

sed -i '' -e 's/subdomainA/subdomainB/g' $(find /home/www/ -type f)

참고 : -i ''OSX 문제 해결sed: 1: "...": invalid command code .

참고 : 처리 할 파일이 너무 많으면 얻을 수 Argument list too long있습니다. 해결 방법 – 위에서 설명한 사용 find -exec또는 xargs솔루션.


4
workaround모든 경우에 선호 구문해야한다.
Reinstate Monica 제발

1
명령 대체의 문제점 $(find...)은 쉘이 공백 또는 다른 쉘 메타 문자가있는 파일 이름을 처리 할 수있는 방법이 없다는 것입니다. 이것이 문제가되지 않는다는 것을 알고 있다면 이 방법은 좋습니다 . 그러나이 문제에 대해 사람들이 경고하지 않았거나 경고를 이해하지 못하는 질문이 너무 많습니다.
tripleee 2012 년

30

실버 검색기를 사용하는 사람 ( ag)

ag SearchString -l0 | xargs -0 sed -i 's/SearchString/Replacement/g'

ag는 기본적으로 git / hg / svn 파일 / 폴더를 무시하므로 저장소 내에서 실행하는 것이 안전합니다.


16

여분의 멋진 oneliner. 자식 grep 사용하기.

git grep -lz 'subdomainA.example.com' | xargs -0 perl -i'' -pE "s/subdomainA.example.com/subdomainB.example.com/g"

3
git repo 내부에서 작업하는 경우 .git / 내용을 덮어 쓸 위험이 없습니다 (다른 답변에 대한 의견에보고 된 바와 같이).
mahemoff

1
고마워, 나는 그것을 bash 함수 refactor() { echo "Replacing $1 by $2 in all files in this git repository." git grep -lz $1| xargs -0 perl -i'' -pE "s/$1/$2/g" }사용법으로 사용합니다. 예를 들어 'word'를 'sword'로 바꾸려면 refactor word sword다음과 같이하십시오 git diff.
Paul Rougieux

16

재귀 할 파일을 줄이기 위해 sed당신이 수를 통해 grep당신의 문자열 예를 들면 :

grep -rl <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

실행 man grep하면 --exlude-dir="*.git"다른 사람들이 정중하게 지적한대로 git 색인 문제를 피하면서 .git 디렉토리를 통한 검색을 생략하려는 경우 플래그를 정의 할 수도 있습니다 .

당신을 이끌 :

grep -rl --exclude-dir="*.git" <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

13

이것은 git 저장소와 호환되며 조금 더 간단합니다.

리눅스 :

git grep -l 'original_text' | xargs sed -i 's/original_text/new_text/g'

맥:

git grep -l 'original_text' | xargs sed -i '' -e 's/original_text/new_text/g'

( http://blog.jasonmeridth.com/posts/use-git-grep-to-replace-strings-in-files-in-your-git-repository/ 감사합니다 )


현명한 사용하기 git-grep-z와 함께 옵션을 xargs -0.
gniourf_gniourf

git grep분명히 git레포 에서만 의미가 있습니다. 일반적인 대체는입니다 grep -r.
tripleee

@gniourf_gniourf 설명 할 수 있습니까?
Petr Peller

2
@PetrPeller :과 -z, git-grep널 (null)에 의한 출력 필드 바꿈 대신 바이트 분리한다; 과와 -0, xargs입력이 대신 공백의, 널 (null) 바이트로 구분 읽기 (그리고 따옴표와 함께 이상한 물건을하지) 않습니다. 따라서 파일 이름에 공백, 따옴표 또는 기타 재미있는 문자가 포함되어 있으면 명령이 중단되지 않게하려면 명령은 다음과 같습니다 git grep -z -l 'original_text' | xargs -0 sed ....
gniourf_gniourf

10
find /home/www/ -type f -exec perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

find /home/www/ -type f / home / www / (및 하위 디렉토리)에있는 모든 파일을 나열합니다. "-exec"플래그는 찾은 각 파일에서 다음 명령을 실행하도록 find에 지시합니다.

perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

파일에서 한 번에 많은 명령을 실행합니다. 은 {}파일 이름으로 대체됩니다. +명령의 끝은 알 수 find많은 파일 이름에 대해 하나 개의 명령을 구축 할 수 있습니다.

find매뉴얼 페이지에 따르면 : "명령 줄은 xargs가 명령 줄을 만드는 것과 거의 같은 방식으로 작성됩니다."

따라서 xargs -0또는 을 사용하지 않고 목표를 달성하고 공백이 포함 된 파일 이름을 처리 할 수 ​​있습니다 -print0.


8

방금 이것을 필요로했으며 사용 가능한 예제의 속도에 만족하지 않았습니다. 그래서 나는 내 자신을 생각해 냈습니다.

cd /var/www && ack-grep -l --print0 subdomainA.example.com | xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'

Ack-grep은 관련 파일을 찾는 데 매우 효율적입니다. 이 명령은 ~ 145 000 파일을 산들 바람으로 바꾸는 반면 다른 사람들은 너무 오래 걸렸기 때문에 끝날 때까지 기다릴 수 없었습니다.


니스,하지만 grep -ril 'subdomainA' *어디 근처로 빨리이다 grep -Hr 'subdomainA' * | cut -d: -f1.
trusktr

@Henno : 단 한 가지 질문 : 바이너리 파일 (실행 파일)을 어떻게 제외시킬 수 있습니까?
user2284570

ack-grep은 자동으로이를 수행합니다.
Henno

@Henno : 쉘 스크립트를 포함합니까?
user2284570

예. 지원되는 파일 형식의 전체 목록은 다음과 같습니다. beyondgrep.com/documentation
Henno

6

디렉토리 ( --exclude-dir=.svn) 를 제외 해야 하고 공백 이있는 파일 이름 이있는 경우 간단한 방법 입니다 ( grep -Zxargs -0

grep -rlZ oldtext . --exclude-dir=.svn | xargs -0 sed -i 's/oldtext/newtext/g'

6

바꾸는 가장 간단한 방법 ( 모든 파일, 디렉토리, 재귀 )

find . -type f -not -path '*/\.*' -exec sed -i 's/foo/bar/g' {} +

참고 : 때때로 일부 숨겨진 파일을 무시해야 할 수도 있습니다. 즉 .git, 위 명령을 사용할 수 있습니다.

숨겨진 파일 사용을 포함하려면

find . -type f  -exec sed -i 's/foo/bar/g' {} +

두 경우 모두 문자열 foo이 새 문자열로 바뀝니다.bar


5

grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done

나는 대부분의 사람들이 무언가를 "읽는 동안 파일"로 파이프 할 수 있다는 것을 모른다고 생각하며 파일 이름에 공백을 두는 반면 불쾌한 -print0 인수를 피합니다.

echosed 앞에를 추가하면 실제로 파일을 변경하기 전에 어떤 파일이 변경되는지 확인할 수 있습니다.


그 이유 -print0while read단순히 처리 할 수없는 경우를 처리하기 때문 입니다 . 개행은 Unix 파일 이름의 유효한 문자이므로 코드가 완전히 강력하려면 해당 파일 이름에도 대처해야합니다. (또한 read -r일부 성가신 POSIX 레거시 동작을 피하고 싶습니다 read.)
tripleee

또한 sed일치하는 항목이없는 경우에는 아무 작업 grep도하지 않으므로 실제로 필요하지 않습니다. 일치하는 내용이 포함되지 않은 파일을 많이 쓰지 않거나 파일의 날짜 스탬프를 불필요하게 업데이트하지 않으려는 경우 재 작성을 피하는 데 유용한 최적화 방법입니다.
tripleee

5

awk를 사용하여 아래와 같이 해결할 수 있습니다.

for file in `find /home/www -type f`
do
   awk '{gsub(/subdomainA.example.com/,"subdomainB.example.com"); print $0;}' $file > ./tempFile && mv ./tempFile $file;
done

희망이 당신을 도울 것입니다!


문제없이 MacO에서 작동합니다! sedosx 특정 설정으로 바이너리가 포함 된 경우 모든 기반 명령이 실패했습니다.
Jankapunkt

조심하십시오 ...이 파일 중 하나라도 find이름에 공백이 있으면 폭발 할 것입니다 ! 그것은 사용하는 것이 훨씬 안전합니다 while read: stackoverflow.com/a/9612560/1938956
소렌 Bjornstad에게

4

이 시도:

sed -i 's/subdomainA/subdomainB/g' `grep -ril 'subdomainA' *`

1
안녕하세요 @RikHic, 좋은 팁-이것에 대해 생각하고있었습니다; 내가 미리 태그로 노력하겠습니다 권리 : 그래서 위의 포맷하면 아주 (작동하지 않습니다) 판명하지 않았다 불행하게도 - 그럼 역 따옴표 탈출로 : sed -i 's/subdomainA/subdomainB/g'` grep -ril 'subdomainA' /home/www/*`-이 아직도 너무 좋은 모두를 보이지만해야하지 않습니다 copypaste에서 살아남으십시오 :) 건배!
sdaau

4
#!/usr/local/bin/bash -x

find * /home/www -type f | while read files
do

sedtest=$(sed -n '/^/,/$/p' "${files}" | sed -n '/subdomainA/p')

    if [ "${sedtest}" ]
    then
    sed s'/subdomainA/subdomainB/'g "${files}" > "${files}".tmp
    mv "${files}".tmp "${files}"
    fi

done

4

블로그 게시물 에 따르면 :

find . -type f | xargs perl -pi -e 's/oldtext/newtext/g;'

슬래시를 어떻게 피 /합니까? 예를 들어, IP 주소를 바꾸고 싶습니다. xxx.xxx.xxx.xxxforxxx.xxx.xxx.xxx/folder
Pathros

/with \를 이스케이프 처리 할 수 ​​있습니다 . 예 :find . -type f | xargs perl -pi -e 's/xxx.xxx.xxx.xxx\/folder/newtext/g;'
J.Hpour

3

vim함께 grep또는 find도구를 사용하는 것이 마음에 들지 않으면 이 링크에서 사용자 Gert가 제공 한 답변을 따를 수 있습니다 . .

거래는 다음과 같습니다.

  • 특정 경로에서 바꾸려는 문자열을 재귀 적으로 파악하고 일치하는 파일의 전체 경로 만 사용하십시오. (그것이 될 것 $(grep 'string' 'pathname' -Rl)입니다.

  • (선택 사항) 중앙 디렉토리에서 해당 파일을 사전 백업하려는 경우 다음을 사용할 수도 있습니다. cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'

  • 그 후에 당신은 vim주어진 링크에 제공된 것과 유사한 체계 를 따라 마음대로 편집 / 교체 할 수 있습니다 :

    • :bufdo %s#string#replacement#gc | update

2

약간 오래된 학교이지만 OS X에서 작동했습니다.

속임수가 거의 없습니다 :

.sls현재 디렉토리에서 확장자 를 가진 파일 만 편집합니다

• "임의의 특성"으로 평가되지 않도록 .탈출해야합니다.sed

• 평소 대신 구분 기호 ,로 사용됩니다.sed/

또한 이것은 Jinja 템플릿을 편집 variable하여 경로에 a를 전달하는 것 입니다 import(그러나 이것은 주제가 아닙니다).

먼저 sed 명령이 원하는 것을 수행하는지 확인하십시오 (이것은 stdout에 대한 변경 사항 만 인쇄하고 파일은 변경되지 않습니다).

for file in $(find . -name *.sls -type f); do echo -e "\n$file: "; sed 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file; done

변경 준비가되면 필요에 따라 sed 명령을 편집하십시오.

for file in $(find . -name *.sls -type f); do echo -e "\n$file: "; sed -i '' 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file; done

을 참고 -i ''나오지도 내가 (에 설명 된대로 원본 파일의 백업을 생성하고 싶지 않았다, 명령 OS X에 나오지으로 다른 위치에서 편집 이 페이지 또는 로버트 Lujo의 의견에).

행복한 seding 사람들!


2

또한 변경을 피하기 위해

  • NearlysubdomainA.example.com
  • subdomainA.example.comp.other

그러나 여전히

  • subdomainA.example.com.IsIt.good

(도메인 루트의 아이디어에는 좋지 않을 수 있습니다)

find /home/www/ -type f -exec sed -i 's/\bsubdomainA\.example\.com\b/\1subdomainB.example.com\2/g' {} \;

2

난 그냥 탑을 사용합니다 :

find . -name '*.[c|cc|cp|cpp|m|mm|h]' -print0 |  xargs -0 tops -verbose  replace "verify_noerr(<b args>)" with "__Verify_noErr(<args>)" \
replace "check(<b args>)" with "__Check(<args>)" 

플러스 '하나씩'* [C | CC | CP | CPP | m | mm | H]. ''
FractalSpace

2

여기에 가장 일반적인 버전이 있습니다. 예를 들어 필요하지 않습니다 find( du대신 사용). 그것은 필요 않습니다 xargs단지 계획 (9) (같은 9front)의 일부 버전에서 발견되는.

 du -a | awk -F' '  '{ print $2 }' | xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'

파일 확장자와 같은 필터를 추가하려면 grep다음을 사용하십시오 .

 du -a | grep "\.scala$" | awk -F' '  '{ print $2 }' | xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'

1

IBMi에서 Qshell (qsh)의 경우 OP로 태그 지정된대로 bash가 아닙니다.

qsh 명령의 한계 :

  • find에는 -print0 옵션이 없습니다
  • xargs에는 -0 옵션이 없습니다
  • sed에는 -i 옵션이 없습니다

따라서 qsh의 솔루션은 다음과 같습니다.

    PATH='your/path/here'
    SEARCH=\'subdomainA.example.com\'
    REPLACE=\'subdomainB.example.com\'

    for file in $( find ${PATH} -P -type f ); do

            TEMP_FILE=${file}.${RANDOM}.temp_file

            if [ ! -e ${TEMP_FILE} ]; then
                    touch -C 819 ${TEMP_FILE}

                    sed -e 's/'$SEARCH'/'$REPLACE'/g' \
                    < ${file} > ${TEMP_FILE}

                    mv ${TEMP_FILE} ${file}
            fi
    done

주의 사항 :

  • 오류 처리를 제외한 솔루션
  • OP 태그로 Bash가 아님

따옴표와 함께 행을 읽는 것과 관련된 성가신 문제가 for있습니다.
tripleee

1

SVN 저장소를 완전히 파괴하지 않고 이것을 사용하려면 다음을 수행하여 숨겨진 파일을 모두 무시하도록 'find'에 지시하십시오.

find . \( ! -regex '.*/\..*' \) -type f -print0 | xargs -0 sed -i 's/subdomainA.example.com/subdomainB.example.com/g'

괄호는 불필요한 것으로 보입니다. 이전에는 형식 오류로 인해 사용할 수 없었습니다 (마크 다운 렌더링은 정규식에서 일부 문자를 먹습니다).
tripleee 2019

1

의 조합을 사용 grep하고sed

for pp in $(grep -Rl looking_for_string)
do
    sed -i 's/looking_for_string/something_other/g' "${pp}"
done

@tripleee 나는 이것을 조금 수정했다. 이 경우 grep -Rl pattern패턴이있는 명령 생성 파일 목록에 대한 출력 입니다. for루프 에서 파일을 읽지 않습니다 .
Pawel

응? 여전히 for루프가 있습니다. 반환 된 파일 이름에 공백이 있으면 셸이 for인수 목록을 토큰 화하므로 제대로 작동하지 않습니다 . 그러나 루프 내에서 따옴표없이 파일 이름 변수를 사용하므로이를 수정하면 대신 중단됩니다. 이 나머지 버그를 수정하면 @ MadMan2064의 답변과 동일하게됩니다.
tripleee 2019

@tripleee 네, 사실입니다.
Pawel

1

git 저장소에서 모든 발생을 바꾸려면 다음을 사용할 수 있습니다.

git ls-files -z | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'

로컬 git repo의 파일 목록을 참조하십시오 . 다른 옵션은 저장소의 모든 파일을 나열합니다. -z옵션은 git에게 파일 이름을 0 바이트로 분리하도록 지시합니다. 이 옵션을 xargs사용하면 -0공백이 있거나 포함되지 않은 경우에도 파일 이름을 분리 할 수 ​​있습니다.


1
perl -p -i -e 's/oldthing/new_thingy/g' `grep -ril oldthing *`

1
awk/를 사용하지 sed않지만 perl이 일반적입니다 (통화 상자가있는 임베디드 / 시스템 만 제외).
pevik

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.