명령을 사용하여 파일 내에서 텍스트 찾기 및 바꾸기


답변:


1053
sed -i 's/original/new/g' file.txt

설명:

  • sed = 스트림 교육자
  • -i = 내부 (즉, 원본 파일로 다시 저장)
  • 명령 문자열 :

    • s = 대체 명령
    • original = 대체 할 단어를 설명하는 정규식 (또는 단어 자체)
    • new = 대체 할 텍스트
    • g = 전역 (즉, 첫 번째 항목뿐만 아니라 모두 대체)
  • file.txt = 파일 이름


3
@Akiva 당신이 검색에 정규 표현식 특수 문자 를 포함 sed하면 일치합니다. -r확장 RE를 대신 사용하려면 플래그를 추가하십시오 .
cscarney

32
@mcExchange 특별히 /일치해야하는 문자 인 경우 다른 문자를 구분 기호 (예 :)로 사용할 수 있습니다 's_old/text_new/text_g'. 그렇지 않으면 리터럴 문자를 얻기 위해 \ 앞에를 둘 수 있습니다 $ * . [ \ ^.
cscarney

3
@BrianZ 파일 시스템에 관한 한 sed의 출력은 이름이 같은 새 파일입니다. 그것은 하나의 버그가 아닌 일반적으로보고 된 버그
cscarney

16
OSX 명령 sed -i '.bak' 's/original/new/g' file.txt은 길이가 0 인 확장으로 실행될 수 있으며 sed -i '' 's/original/new/g' file.txt백업을 생성하지 않습니다.
Kirk

19
MacOS 사용자는 -i 뒤에 '' "를 -i ed.gs/2016/01/26/os-x-sed-invalid-command-code 의 매개 변수로 추가 하여 파일을 덮어
써야합니다

32

이를 수행하는 방법에는 여러 가지가 있습니다. 하나는 sedRegex를 사용 하고 있습니다. SED는 텍스트를 필터링하고 변환하기위한 스트림 편집기입니다. 한 가지 예는 다음과 같습니다.

marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog

보다 더 많은 의미를 수있는 또 다른 방법 < strin과는 > strout파이프입니다!

marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai 
The quick brown fox jumped over the lazy sleeping dog

6
메모 cat의가 cat file | sed '...'필요하지 않습니다. 직접 말할 수 있습니다 sed '...' file.
fedorqui

1
실제로 이것은 더 줄어들 수 있습니다 : sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly파일을 씩씩 가져 가면 백업을 수행하는 동안 두 가지 변경 사항이 적용됩니다. time bash -c "$COMMAND"시간을 사용하면 이 버전이 ~ 5 배 빠릅니다.
pbhj

23

그것을 달성하는 방법에는 여러 가지가 있습니다. 문자열 대체로 달성하려는 작업의 복잡성과 사용자가 익숙한 도구에 따라 일부 방법이 다른 방법보다 선호 될 수 있습니다.

이 답변에서는 간단한 input.txt파일을 사용하고 있습니다.이 파일은 여기에 제공된 모든 예제를 테스트하는 데 사용할 수 있습니다. 파일 내용 :

roses are red , violets are blue
This is an input.txt and this doesn't rhyme

세게 때리다

Bash는 실제로 텍스트 처리를위한 것이 아니지만 매개 변수 확장을 통해 간단한 대체를 수행 할 수 있습니다 . 특히 여기서 간단한 구조를 사용할 수 있습니다 ${parameter/old_string/new_string}.

#!/bin/bash
while IFS= read -r line
do
    case "$line" in
       *blue*) printf "%s\n" "${line/blue/azure}" ;;
       *) printf "%s\n" "$line" ;;
    esac
done < input.txt

이 작은 스크립트는 대체 텍스트를 대체하지 않습니다. 즉, 새 텍스트를 새 파일에 저장하고 이전 파일을 제거해야합니다. mv new.txt old.txt

참고 : 왜 while IFS= read -r ; do ... done < input.txt사용 되는지 궁금하다면 기본적으로 파일을 한 줄씩 읽는 쉘의 방법입니다. 참고 이를 참조하십시오.

AWK

텍스트 처리 유틸리티 인 AWK는 이러한 작업에 매우 적합합니다. 정규 표현식을 기반으로 간단한 대체와 훨씬 더 고급 교체를 수행 할 수 있습니다 . 이 두 가지 기능을 제공 sub()하고 gsub(). 첫 번째는 첫 번째 항목 만 대체하고 두 번째는 전체 문자열에서 발생을 대체합니다. 예를 들어, string one potato two potato이 있으면 결과는 다음과 같습니다.

$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana

$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'                                      
one banana two potato 

AWK는 입력 파일을 인수로 사용할 수 있으므로와 같은 작업을 수행하는 input.txt것이 쉽습니다.

awk '{sub(/blue/,"azure")}1' input.txt

보유하고있는 AWK의 버전에 따라 편집 중일 수도 있고 없을 수도 있으므로 일반적인 방법은 새 텍스트를 저장하고 바꾸는 것입니다. 예를 들면 다음과 같습니다.

awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt

SED

Sed는 라인 편집기입니다. 또한 정규 표현식을 사용하지만 간단한 대체를 위해서는 충분합니다.

sed 's/blue/azure/' input.txt

이 도구의 장점은 바로 편집 할 수 있다는 것 -i입니다.

Perl은 텍스트 처리에 자주 사용되는 또 다른 도구이지만 범용 언어이며 네트워킹, 시스템 관리, 데스크톱 앱 및 기타 여러 장소에서 사용됩니다. C, sed, awk 등과 같은 다른 언어에서 많은 개념 / 기능을 빌 렸습니다. 다음과 같이 간단한 대체를 수행 할 수 있습니다.

perl -pe 's/blue/azure/' input.txt

sed와 마찬가지로 perl에도 -i 플래그가 있습니다.

파이썬

이 언어는 매우 다재다능하며 다양한 응용 분야에서도 사용됩니다. 그것은 어느 사이에, 문자열 작업을위한 기능을 많이 가지고 replace(), 그래서 당신은 같은 변수가 있다면 var="Hello World", 당신은 할 수var.replace("Hello","Good Morning")

파일을 읽고 문자열을 바꾸는 간단한 방법은 다음과 같습니다.

python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt

그러나 Python을 사용하면 새 파일로 출력해야하며 스크립트 자체에서 수행 할 수도 있습니다. 예를 들어 다음은 간단한 것입니다.

#!/usr/bin/env python
import sys
import os
import tempfile

tmp=tempfile.mkstemp()

with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
    for line in fd1:
        line = line.replace('blue','azure')
        fd2.write(line)

os.rename(tmp[1],sys.argv[1])

이 스크립트는 input.txt명령 행 인수로 호출됩니다 . 명령 행 인수로 파이썬 스크립트를 실행하는 정확한 명령은 다음과 같습니다.

 $ ./myscript.py input.txt

또는

$ python ./myscript.py input.txt

물론, ./myscript.py현재 작업 디렉토리에 있는지 확인 하고 첫 번째 방법으로 실행 가능하게 설정하십시오.chmod +x ./myscript.py

파이썬은 정규 표현식을 가질 수 있습니다. 특히 re모듈 이 있습니다.이 모듈에는 re.sub()더 고급 교체에 사용할 수 있습니다.


1
좋은 편집! 여기에 언급되지 않은 또 다른 가능한 방법 tr은 유닉스 에서 명령을 사용하는 것입니다
Tapajit Dey

1
@TapajitDey 예, tr 또 다른 훌륭한 도구이지만, (예를 들어 문자 세트를 교체하기위한 것입니다 점에 유의 tr abc cde번역 할 ac, bd그것은에서와 같이 전체 단어를 교체에서 약간 다릅니다. sedpython
세르지 Kolodyazhnyy

22

Ex 모드에서 Vim을 사용할 수 있습니다 :

ex -s -c '%s/OLD/NEW/g|x' file
  1. % 모든 줄을 선택하십시오

  2. s 대용품

  3. g 각 줄의 모든 인스턴스를 교체

  4. x 변경 사항이 있으면 작성하고 종료하십시오.


21

awk의 gsub 명령을 통해

awk '{gsub(/pattern/,"replacement")}' file

예:

awk '{gsub(/1/,"0");}' file

위의 예에서 열이 어디에 있든지 상관없이 1은 모두 0으로 바뀝니다.


특정 열에서 교체하려면 다음과 같이하십시오.

awk '{gsub(/pattern/,"replacement",column_number)}' file

예:

awk '{gsub(/1/,"0",$1);}' file

첫 번째 열에서만 1을 0으로 바꿉니다.

펄을 통해

$ echo 'foo' | perl -pe 's/foo/bar/g'
bar

나는 이것을 MacOS 터미널에서 사용했는데 아무것도하지 않았다.
Jim

(도커 컨테이너) 알파인 리눅스에서 테스트하고 더 출력 없어
Salathiel 만들어진 Genese

@ SalathielGenèse 무엇을 달성하려고 노력하고 있습니까?
Avinash Raj

내가 가진 파일을보고 있어요 inotifywait아래 shENV, 그리고 (사용자 정의 형식이 버그 때문에) CSV 형식의 데이터를보고. 그런 다음 쉘 스크립트에서 CSV 문서를 처리하는 간단한 방법이 없다고 생각했습니다. 그래서 CSV를 구문 분석하고보고하는 매우 간단한 스크립트를 시작했습니다. CSV 사양을 읽고 예상보다 정교하고 큰 따옴표로 묶은 여러 줄 값을 지원하는 것으로 나타났습니다. 나는 sed토큰 화 에 의존 했지만 곧 여러 sed줄을 호출하는 것이 최대 두 줄 이라는 것을 깨달았 습니다. CSV 값 중 하나가 두 줄 이상에 걸쳐 있으면 어떻게됩니까?
Salathiel Genèse

문제를 질문으로하는 것이 좋습니다.
Avinash Raj

8

sedS tream 에드 당사 홈페이지에서 , 당신이 사용할 수에 |보내 (파이프) 표준 스트림 을 통해 (STDIN과 STDOUT 특별히을) sed과 유닉스 철학의 전통에 편리한 도구 만들기, 즉석에서 프로그램을 변경하는 행위 -i아래 언급 된 매개 변수를 사용하여 파일을 직접 편집 할 수도 있습니다.
다음을 고려하십시오 .

sed -i -e 's/few/asd/g' hello.txt

s/에 사용되는 의 것은 발견 된 표현을 ubstitute fewasd:

용감한 소수.


바보, 용감한.

/g"전역 (global)"을 의미하며, 전체 라인에서이를 수행한다는 의미입니다. 를 사용하지 않고 /g(와 함께 s/few/asd/항상 3 개의 슬래시가 있어야 함) few같은 줄에 두 번 나타나는 경우 첫 번째 만 다음 few으로 변경됩니다 asd.

소수의 남자, 소수의 여자, 용감한.


엉덩이 남자, 몇 여자, 용감한.

이것은 줄의 시작 부분에 특수 문자를 변경하는 것과 같은 일부 상황에서 유용합니다 (예를 들어, 일부 사람들이 이메일 스레드에서 이전 자료를 가로 탭으로 인용하는 데 사용되는 것보다 큰 기호를 대체하면서 인용 된 대수 부등식은 나중에 줄에 표시 함) 손길이 닿지 않는 곳), 어디서나 few 발생하도록 지정하는 예에서는 교체해야합니다 /g.

다음 두 옵션 (플래그)이 하나로 결합됩니다 -ie.

-i옵션을 편집하는 데 사용됩니다 내가 N 파일에 배치합니다 hello.txt.

-e옵션은이 경우 e xpression / 명령을 나타냅니다 s/.

참고 : -i -e검색 / 바꾸는 데 사용 하는 것이 중요합니다 . 이 경우 -ie문자 'e'가 추가 된 모든 파일의 백업을 만듭니다.


2

당신은 이렇게 할 수 있습니다 :

locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g" 

예 : locate 명령의 결과 인 모든 파일에서 모든 발생 [logdir ',' '] ([]없이)를 [logdir', os.getcwd ()]로 바꾸려면 다음을 수행하십시오.

ex1 :

locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"

ex2 :

locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"

여기서 [tensorboard / program.py]는 검색 할 파일입니다.


안녕하세요. 문자열 ( logdir', ''-> /logdir', os.getcwd())을 선택하면이 답변을 구문 분석하기가 어렵습니다. 또한 답이 sed에서 사용할 파일을 먼저 찾도록 지정하는 것이 좋습니다. 질문의 일부가 아니기 때문입니다.
mwfearnley

안녕하세요,이 대답은 파일에서 <이전 텍스트>를 찾은 경우 모두 검색하고 모두 바꿉니다.
Nguyễn Tuấn Anh

로그 폴더에 머물 때 tensorboard --logdir = '/ path / to / log / folder /'에서 다음 명령을 변경하려는 keras에서 tensorboard를 사용하는 모든 사람에 대해이 답변을 선택합니다. 그것은 매우 편리합니다
응 우옌 투안 안
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.