답변:
cd /path/to/your/folder
sed -i 's/foo/bar/g' *
"foo"가 발생하면 "bar"로 바뀝니다.
macOS와 같은 BSD 시스템 -i '.bak'
에서는 맨 페이지마다 "위험 손상 또는 부분 내용" 과 같은 백업 확장명을 제공해야합니다 .
cd /path/to/your/folder
sed -i '.bak' 's/foo/bar/g' *
sed
, -i
이전 파일 이름에 추가되어 그 후 문자열이 필요합니다. 따라서 sed -i .bak 's/foo/bar/g' *.xx
모든 .xx
파일을 동등한 .xx.bak
이름으로 옮긴 다음 .xx
foo → bar로 파일 을 생성하십시오 .
sed -i 's/foo\ with\ spaces/bar/g' *
. 오랫동안 당신이 알게 된 것 같습니다 ... 그러나이 방법은 다른 사람들이 같은 문제를 찾는 데있어 유지됩니다.
sed -i -e 's/foo/bar/g' $(find /home/user/base/dir)
Kaspar의 답변과 비슷하지만 g 플래그를 사용하여 모든 행을 대체합니다.
find ./ -type f -exec sed -i 's/string1/string2/g' {} \;
대소 문자를 구분하지 않는 경우 :
find ./ -type f -exec sed -i 's/string1/string2/gI' {} \;
LC_ALL=C find ./ -type f -exec sed -i '' -e 's/proc.priv/priv/g' {} \;
( 이 게시물 및 이 파일 참조 )
--include=*.whatever
되었습니다. -r
.git/
. cd
더 낮은 레벨 로 내려야합니다.
git status
반환합니다 error: bad index file sha1 signature.... fatal: index file corrupt
. 무엇을 제공합니까?
@kev의 대답은 좋지만 직접 디렉토리의 파일에만 영향을 미칩니다. 아래 예는 grep을 사용하여 파일을 재귀 적으로 찾습니다. 그것은 매번 나를 위해 작동합니다.
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
명령 분석
grep -r : --recursive , 각 디렉토리의 모든 파일을 재귀 적으로 읽습니다.
grep -l : --print-with-matches 는 일치하는 줄을 인쇄하는 대신 일치하는 각 파일의 이름을 인쇄합니다.
grep -i : --ignore-case .
xargs : STDIN을 인수로 변환하십시오 . 이 답변을 따르십시오 .
xargs -i @ ~ command에는 @ ~ : ~ command ~ 의 특정 위치에서 사용될 인수의 자리 표시자가 포함되어 있으며 @ 기호는 모든 문자열로 대체 할 수있는 자리 표시 자입니다.
sed -i : 백업 없이 파일을 편집합니다 .
sed s / regexp / replacement / : regexp 와 교체 문자열 일치 .
sed s / regexp / replacement / g : global , 첫 번째 일치 만이 아니라 각 일치를 대체하십시오.
grep --include={*.php,*.html,*.js} -rnl './' -e "old-word" | xargs -i@ sed -i 's/old-word/new-word/g' @
|
해야하는지 왜 -i
xargs 명령에서 사용 해야하는지 모르겠습니다 . 설명서에서 더 이상 사용되지 않으며 -I
대신 사용해야 합니다. 그리고되는 @
패턴의 시작과 끝의 구분 기호로 사용?
grep -rli 'old-word' * | xargs -I@ sed -i '' 's/2.0.0/latest/g' @
rli
)와 @
예를 들어 표시를
이것은 나를 위해 일했다 :
find ./ -type f -exec sed -i 's/string1/string2/' {} \;
그러나, 이것은하지 않았다 : sed -i 's/string1/string2/g' *
. "foo"는 string2가 아니며 "bar"는 string2가 아닙니다.
find ./ -type f -exec sed -i '' -e 's/string1/string2/' {} \;
이에 대한 몇 가지 표준 답변이 이미 나열되어 있습니다. 일반적으로 find 를 사용 하여 파일을 재귀 적으로 나열한 다음 sed 또는 perl을 사용 하여 작업을 수행 할 수 있습니다 .
가장 빠른 사용을 위해 rpl 명령 을 기억하기가 훨씬 쉽다는 것을 알 수 있습니다. 다음은 모든 파일에서 재귀 적으로 대체 (foo-> bar)입니다.
rpl -R foo bar .
설치해야 할 수도 있습니다 ( apt-get install rpl
또는 유사).
그러나 정규 표현식과 역 치환 또는 파일 이름 바꾸기 및 검색 및 교체와 관련된 힘든 작업의 경우 내가 알고있는 가장 일반적이고 강력한 도구는 repren 이며, 일부는 작은 Python 스크립트였습니다. 가시적 인 이름 바꾸기 및 리팩토링 작업. 선호하는 이유는 다음과 같습니다.
이스케이프 문자를 제외하고 파일 내의 경로를 바꾸려면 다음 명령을 사용할 수 있습니다.
sed -i 's@old_path@new_path@g'
@ 기호는 모든 특수 문자가 다음 문자열에서 무시되어야 함을 의미합니다.
"foo"의 첫 번째 줄은 "bar"로 바뀝니다. 그리고 두 번째 줄을 사용하여 확인할 수 있습니다.
grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
grep 'foo' -r * | awk -F: {'print $1'} | sort -n | uniq -c
grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
파일 목록이 있으면 사용할 수 있습니다
replace "old_string" "new_string" -- file_name1 file_name2 file_name3
모든 파일이 있으면 사용할 수 있습니다
replace "old_string" "new_string" -- *
확장자가있는 파일 목록이있는 경우 사용할 수 있습니다
replace "old_string" "new_string" -- *.extension
replace "old_string" "new_string" -- *.txt
replace
유틸리티 를 얻을 수있는 곳에서 추가하는 것이 좋습니다 . 이 정보가 없으면이 답변은 불완전합니다.
"찾기와 sed를 사용할 수도 있지만이 작은 펄 라인은 훌륭하게 작동합니다.
perl -pi -w -e 's/search/replace/g;' *.php
"( http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php 에서 발췌 )
내 최고의 결과는 perl과 grep을 사용하여 얻은 것입니다 (파일에 검색 표현식이 있는지 확인하기 위해)
perl -pi -w -e 's/search/replace/g;' $( grep -rl 'search' )
문자열을 검색하여 여러 파일로 search
바꾸려면 내 전투 테스트 한 줄 공식입니다 .replace
grep -RiIl 'search' | xargs sed -i 's/search/replace/g'
빠른 grep 설명 :
-R
-재귀 검색-i
-대소 문자 구분-I
-바이너리 파일을 건너 뛰십시오 (텍스트를 원하십니까?)-l
-간단한 목록을 출력으로 인쇄하십시오. 다른 명령에 필요grep 출력은 실제로 텍스트를 대체하는 데 사용되는 sed (xargs를 통해)로 파이프됩니다. -i
플래그는 파일을 직접 변경됩니다. 일종의 "드라 이런"모드에서는 제거하십시오.
나는이 질문 (및 답변)을 찾기 전에 내 자신의 해결책을 모색했습니다. "replace" "several"과 "xml"의 다른 조합을 검색했습니다. 왜냐하면 그것은 내 응용 프로그램 이었기 때문에이 특정 항목을 찾지 못했습니다.
내 문제 : 복잡한 객체를 포함하는 테스트 사례 데이터가있는 스프링 XML 파일이 있습니다. Java 소스 코드의 리 팩터는 많은 클래스를 변경했으며 xml 데이터 파일에는 적용되지 않았습니다. 테스트 사례 데이터를 저장하기 위해 여러 디렉토리에 분산 된 모든 XML 파일의 모든 클래스 이름을 변경해야했습니다. 원본 xml 파일의 백업 사본을 저장하는 동안 (버전 제어가 나를 저장하기 때문에 반드시 필요한 것은 아니지만).
나는 다른 상황에서 나를 위해 일했지만 한 번에 여러 번 교체하지 않기 때문에 find
+의 조합을 찾고있었습니다 sed
.
그런 다음 ubuntu 응답 요청을 발견 하여 명령 줄을 작성하는 데 도움이되었습니다.
find -name "*.xml" -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;
그리고 그것은 완벽하게 작동했습니다 (글쎄, 내 경우에는 6 가지 교체가있었습니다). 그러나 현재 디렉토리 아래의 모든 * .xml 파일을 터치합니다. 따라서 버전 제어 시스템에 대한 책임이있는 경우 먼저 필터링하고 sed
실제로 원하는 문자열을 가진 사용자 에게만 전달할 수 있습니다. 처럼:
find -name "*.xml" -exec grep -e "firstWord" -e "secondWord" -e "thirdWord" {} \; -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;
findstr /spin /c:"quéquieresbuscar" *.xml
.
MacBook Pro에서 다음을 사용했습니다 ( https://stackoverflow.com/a/19457213/6169225 ).
sed -i '' -e 's/<STR_TO_REPLACE>/<REPLACEMENT_STR>/g' *
-i ''
백업을하지 않을 것입니다.
-e
현대 정규식.
-e
sed에게 다음 토큰이 명령이라고 알려줍니다. 확장 정규 표현식의 경우 -E
대신 사용하십시오.
스트림 편집기는 -i
스위치로 호출 될 때 여러 파일을 "inplace"로 수정 하며 백업 파일은 인수로 끝납니다. 그래서
sed -i.bak 's/foo/bar/g' *
을 대체 foo
와 bar
이 폴더의 모든 파일에 있지만은 하위 폴더로 내려하지 않습니다. 그러나 이것은 .bak
디렉토리의 모든 파일에 대해 새 파일을 생성합니다 . 이 디렉토리 및 모든 서브 디렉토리의 모든 파일에 대해이 작업을 반복적으로 수행하려면 find
디렉토리 트리를 순회하기 위한 도우미가 필요합니다 .
find ./ -print0 | xargs -0 sed -i.bak 's/foo/bar/g' *
find
find ./ -name '*.php' -or -name '*.html' -print0
필요한 경우과 같은 추가 인수를 지정하여 수정할 파일에 대한 추가 제한을 허용합니다 .
참고 : GNU sed
는 파일 끝이 필요하지 않으며 sed -i 's/foo/bar/g' *
작동합니다. FreeBSD sed
는 확장을 요구하지만 그 사이에 공백을 허용하므로 sed -i .bak s/foo/bar/g *
작동합니다.
multiedit 명령을위한 스크립트
multiedit [-n PATTERN] OLDSTRING NEWSTRING
Kaspar의 답변에서 명령 줄 인수를 수락하고 선택적으로 패턴과 일치하는 파일 이름을 제한하는 bash 스크립트를 만들었습니다. $ PATH에 저장하고 실행 가능하게 한 다음 위의 명령을 사용하십시오.
스크립트는 다음과 같습니다.
#!/bin/bash
_help="\n
Replace OLDSTRING with NEWSTRING recursively starting from current directory\n
multiedit [-n PATTERN] OLDSTRING NEWSTRING\n
[-n PATTERN] option limits to filenames matching PATTERN\n
Note: backslash escape special characters\n
Note: enclose STRINGS with spaces in double quotes\n
Example to limit the edit to python files:\n
multiedit -n \*.py \"OLD STRING\" NEWSTRING\n"
# ensure correct number of arguments, otherwise display help...
if [ $# -lt 2 ] || [ $# -gt 4 ]; then echo -e $_help ; exit ; fi
if [ $1 == "-n" ]; then # if -n option is given:
# replace OLDSTRING with NEWSTRING recursively in files matching PATTERN
find ./ -type f -name "$2" -exec sed -i "s/$3/$4/g" {} \;
else
# replace OLDSTRING with NEWSTRING recursively in all files
find ./ -type f -exec sed -i "s/$1/$2/" {} \;
fi
파일에 백 슬래시 (일반적으로 경로)가 포함 된 경우 다음과 같이 시도 할 수 있습니다.
sed -i -- 's,<path1>,<path2>,g' *
전의:
sed -i -- 's,/foo/bar,/new/foo/bar,g' *.sh (in all shell scripts available)
개인 영어 노드를 유지하기 위해 디렉토리 아래의 모든 파일에 대해 여러 쌍의 이전 / 새 문자열을 대체하는 유틸리티 스크립트를 재귀 적으로 작성했습니다.
여러 쌍의 이전 / 새 문자열은 해시 맵에서 관리됩니다.
dir은 명령 행 또는 환경 변수를 통해 설정 될 수 있으며 맵은 스크립트로 하드 코딩되지만 필요한 경우 파일에서로드하도록 코드를 수정할 수 있습니다.
새로운 기능으로 인해 bash 4.2가 필요합니다.
en_standardize.sh :
#! /bin/bash
# (need bash 4.2+,)
#
# Standardize phonetic symbol of English.
#
# format:
# en_standardize.sh [<dir>]
#
# params:
# * dir
# target dir, optional,
# if not specified then use environment variable "$node_dir_en",
# if both not provided, then will not execute,
# *
#
paramCount=$#
# figure target dir,
if [ $paramCount -ge 1 ]; then # dir specified
echo -e "dir specified (in command):\n\t$1\n"
targetDir=$1
elif [[ -v node_dir_en ]]; then # environable set,
echo -e "dir specified (in environment vairable):\n\t$node_dir_en\n"
targetDir=$node_dir_en
else # environable not set,
echo "dir not specified, won't execute"
exit
fi
# check whether dir exists,
if [ -d $targetDir ]; then
cd $targetDir
else
echo -e "invalid dir location:\n\t$targetDir\n"
exit
fi
# initial map,
declare -A itemMap
itemMap=( ["ɪ"]="i" ["ː"]=":" ["ɜ"]="ə" ["ɒ"]="ɔ" ["ʊ"]="u" ["ɛ"]="e")
# print item maps,
echo 'maps:'
for key in "${!itemMap[@]}"; do
echo -e "\t$key\t->\t${itemMap[$key]}"
done
echo -e '\n'
# do replace,
for key in "${!itemMap[@]}"; do
grep -rli "$key" * | xargs -i@ sed -i "s/$key/${itemMap[$key]}/g" @
done
echo -e "\nDone."
exit
파이썬 소스에서 일반적인 shebang 오류를 수정하는 예제를 제공합니다.
grep / sed 접근법을 시도 할 수 있습니다. 다음은 GNU sed에서 작동하며 git repo를 깨지 않을 것입니다
$ grep -rli --exclude '*.git*' '#!/usr/bin/python' . | xargs -I {} \
gsed -i '' -e 's/#!\/usr\/bin\/python/#!\/usr\/bin\/env python/' {}
또는 greptile 을 사용할 수 있습니다 :)
$ greptile -x .py -l -i -g '#!/usr/bin/env python' -r '#!/usr/bin/python' .
방금 첫 번째 스크립트를 테스트했으며 두 번째 스크립트도 작동합니다. 탈출 문자에주의하십시오. 대부분의 경우 greptile을 사용하는 것이 더 쉬울 것이라고 생각합니다. 물론, 당신은 sed로 많은 흥미로운 것들을 할 수 있으며, 그것을 위해 xargs로 그것을 사용하는 것이 바람직 할 수 있습니다.
나는 이것을 다른 게시물에서 찾았으며 (어떤 것을 기억할 수는 없다) 가장 우아하지는 않지만 간단하고 초보자로서 Linux 사용자는 나에게 아무런 문제도주지 않았다.
for i in *old_str* ; do mv -v "$i" "${i/\old_str/new_str}" ; done
공백이나 다른 특수 문자가 있으면 \
for i in *old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done
하위 디렉토리의 문자열에 ** 사용
for i in *\*old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done
간단한 스크립트 파일을 사용하면 더 쉬운 방법이 있습니다.
# sudo chmod +x /bin/replace_string_files_present_dir
gedit 또는 선택한 편집기에서 파일을 열면 여기에서 gedit를 사용합니다.
# sudo gedit /bin/replace_string_files_present_dir
그런 다음 편집기에서 파일에 다음을 붙여 넣습니다.
#!/bin/bash
replace "oldstring" "newstring" -- *
replace "oldstring1" "newstring2" -- *
#add as many lines of replace as there are your strings to be replaced for
#example here i have two sets of strings to replace which are oldstring and
#oldstring1 so I use two replace lines.
파일을 저장하고 gedit를 닫습니다 다음 터미널을 종료하거나 다음 추가 한 새 스크립트를로드 할 수 있도록 시작하십시오.
편집하려는 여러 파일이있는 디렉토리로 이동하십시오. 그런 다음 다음을 실행하십시오.
#replace_string_files_present_dir
Enter 키를 누르면 oldstring 및 oldstring1 이 포함 된 모든 파일에서 oldstring 및 oldstring1 이 각각 올바른 newstring 및 newstring1로 자동 바뀝니다 .
이전 문자열을 포함하지 않는 모든 디렉토리와 파일을 건너 뜁니다.
문자열 대체가 필요한 파일이있는 여러 디렉토리가있는 경우 지루한 입력 작업을 없애는 데 도움이 될 수 있습니다. 각 디렉토리로 이동 한 후 다음을 실행하기 만하면됩니다.
#replace_string_files_present_dir
위에서 보여 드린대로 모든 교체 문자열을 포함하거나 추가하기 만하면됩니다.
replace "oldstring" "newstring" -- *
/ bin / replace_string_files_present_dir 파일의 끝에 있습니다.
새 바꾸기 문자열을 추가하려면 터미널에 다음을 입력하여 만든 스크립트를 엽니 다.
sudo gedit /bin/replace_string_files_present_dir
추가하는 교체 문자열 수에 대해 걱정하지 마십시오. 이전 문자열을 찾지 못하면 아무런 영향을 미치지 않습니다.
.gitlab-ci.yml
또는 a travis.yml
) 에 포함 할 컴팩트 버전을 요구합니다 . 당신이 다음 스크립트에 스크립트 생성을해야 나중에 그것을 실행하는 스크립트를 서면으로 구성된 주변의 모든 턴 (내가 지저분한 간다, 대부분의 시간), 안티 - 패턴
$ replace "From" "To"-`find / path / to / folder -type f`
(바꾸기-MySQL 데이터베이스 시스템의 문자열 바꾸기 유틸리티)