[bash] Bash 명령에서 텍스트 파일 내부 찾기 및 바꾸기
찾은 내용을 주어진 입력 문자열을 대체 말할 수있는 가장 간단한 방법은 무엇인가 abc
말을하고, 다른 문자열로 대체 할 XYZ
파일은 /tmp/file.txt
?
앱을 작성하고 IronPython을 사용하여 SSH를 통해 명령을 실행하고 있습니다. 그러나 유닉스를 잘 모르고 무엇을 찾아야할지 모르겠습니다.
Bash는 명령 줄 인터페이스가 아니라 매우 강력한 스크립팅 언어가 될 수 있다고 들었습니다. 따라서 이것이 사실이라면 나는 당신이 이와 같은 행동을 수행 할 수 있다고 가정합니다.
bash로 할 수 있습니까? 목표를 달성하는 가장 간단한 (한 줄) 스크립트는 무엇입니까?
답변
가장 쉬운 방법은 sed (또는 perl)를 사용하는 것입니다.
sed -i -e 's/abc/XYZ/g' /tmp/file.txt
-i
옵션 으로 인해 내부 편집을 수행하기 위해 sed를 호출합니다 . 이것은 bash에서 호출 할 수 있습니다.
정말로 bash 만 사용하고 싶다면 다음과 같이 할 수 있습니다.
while read a; do
echo ${a//abc/XYZ}
done < /tmp/file.txt > /tmp/file.txt.t
mv /tmp/file.txt{.t,}
이것은 각 행을 반복하여 대체를 수행하고 임시 파일에 기록합니다 (입력을 방해하지 않으려 고 함). 마지막 이동은 임시로 원래 이름으로 이동합니다.
답변
파일 조작은 일반적으로 Bash가 아니라 Bash가 호출 한 프로그램에 의해 수행됩니다. 예 :
perl -pi -e 's/abc/XYZ/g' /tmp/file.txt
이 -i
플래그는 내부 교체를 지시합니다.
man perlrun
원본 파일을 백업하는 방법을 포함하여 자세한 내용을 참조하십시오 .
답변
이걸 우연히 발견했을 때 놀랐습니다 …
패키지 replace
와 함께 제공 되는 명령이 "mysql-server"
있으므로 설치 한 경우 시도해보십시오.
# replace string abc to XYZ in files
replace "abc" "XYZ" -- file.txt file2.txt file3.txt
# or pipe an echo to replace
echo "abcdef" |replace "abc" "XYZ"
이에 man replace
대한 자세한 내용 을 참조하십시오 .
답변
이것은 오래된 게시물이지만 @ centurian과 같이 변수를 사용하려는 사람은 작은 따옴표가 아무것도 확장되지 않는다는 것을 의미한다고 말했습니다.
변수를 가져 오는 간단한 방법은 문자열 연결을 수행하는 것입니다. 이는 bash에서 병렬로 수행되므로 다음과 같이 작동합니다.
sed -i -e "s/$var1/$var2/g" /tmp/file.txt
답변
다른 쉘과 마찬가지로 Bash는 다른 명령을 조정하는 도구 일뿐입니다. 일반적으로 표준 UNIX 명령을 사용하려고 시도하지만 Bash를 사용하여 컴파일 된 프로그램, 다른 쉘 스크립트, Python 및 Perl 스크립트 등을 포함하여 무엇이든 호출 할 수 있습니다.
이 경우 몇 가지 방법이 있습니다.
파일을 읽고 다른 파일에 쓰려면 검색 / 바꾸기를 수행하면서 sed를 사용하십시오.
sed 's/abc/XYZ/g' <infile >outfile
편집기에서 파일을 열고 편집 한 후 저장하는 것처럼 파일을 제자리에서 편집하려면 라인 편집기 ‘ex’에 지시 사항을 제공하십시오.
echo "%s/abc/XYZ/g
w
q
" | ex file
Ex는 전체 화면 모드가없는 vi와 같습니다. vi의 ‘:’프롬프트에서와 동일한 명령을 제공 할 수 있습니다.
답변
나는이 스레드를 다른 사람들과 함께 발견했으며 가장 완벽한 답변을 포함하고 있음을 동의하므로 내 것을 추가하고 있습니다.
-
sed
그리고ed
손으로 너무 유용합니다. @Johnny 에서이 코드를보십시오 :sed -i -e 's/abc/XYZ/g' /tmp/file.txt
-
내 제한이 쉘 스크립트에서 사용되는 경우, “abc”또는 “XYZ”대신 변수를 사용할 수 없습니다. BashFAQ은 내가 적어도 이해하는 것을 동의 것으로 보인다. 그래서 나는 사용할 수 없습니다 :
x='abc' y='XYZ' sed -i -e 's/$x/$y/g' /tmp/file.txt #or, sed -i -e "s/$x/$y/g" /tmp/file.txt
그러나 우리는 무엇을 할 수 있습니까? @Johnny는 사용
while read...
하지만 불행히도 그 이야기의 끝은 아닙니다. 다음은 나와 잘 작동했습니다.#edit user's virtual domain result= #if nullglob is set then, unset it temporarily is_nullglob=$( shopt -s | egrep -i '*nullglob' ) if [[ is_nullglob ]]; then shopt -u nullglob fi while IFS= read -r line; do line="${line//'<servername>'/$server}" line="${line//'<serveralias>'/$alias}" line="${line//'<user>'/$user}" line="${line//'<group>'/$group}" result="$result""$line"'\n' done < $tmp echo -e $result > $tmp #if nullglob was set then, re-enable it if [[ is_nullglob ]]; then shopt -s nullglob fi #move user's virtual domain to Apache 2 domain directory ......
-
다음과 같이
nullglob
설정되어 있는지 확인할 수 있듯이*
as를 포함하는 문자열이 있으면 이상하게 동작합니다 .<VirtualHost *:80> ServerName www.example.com
이것은
<VirtualHost ServerName www.example.com
끝 꺾쇠 괄호가 없으며 Apache2도로드 할 수 없습니다.
-
이러한 종류의 구문 분석은 한 번의 검색 및 바꾸기보다 속도가 느려 야하지만 이미 살펴본 것처럼 한 번의 구문 분석주기에서 작동하는 4 가지 다른 검색 패턴에 대한 4 개의 변수가 있습니다.
주어진 문제에 대한 가정으로 생각할 수있는 가장 적합한 솔루션입니다.
답변
당신은 사용할 수 있습니다 sed
:
sed -i 's/abc/XYZ/gi' /tmp/file.txt
사용 -i
이 발견하지 않도록 텍스트 경우 “경우 무시”에 대한은 abc
나 ABC
이나 AbC
등
당신은 사용 find
하고 sed
당신이 당신의 이름을 모르는 경우 :
find ./ -type f -exec sed -i 's/abc/XYZ/gi' {} \;
모든 파이썬 파일에서 찾기 및 바꾸기 :
find ./ -iname "*.py" -type f -exec sed -i 's/abc/XYZ/gi' {} \;