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 -Z및xargs -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 앞에를 추가하면 실제로 파일을 변경하기 전에 어떤 파일이 변경되는지 확인할 수 있습니다.


그 이유 -print0는 while 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.