Sed를 사용하여 문자열이 포함 된 전체 줄을 바꿉니다.


319

다음과 같은 특정 줄이있는 텍스트 파일이 있습니다.

sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext

위의 전체 줄을

This line is removed by the admin.

검색 키워드는 TEXT_TO_BE_REPLACED

이를 위해 쉘 스크립트를 작성해야합니다. 어떻게 이것을 사용하여 이것을 달성 할 수 sed있습니까?


@ Scharron 나는 sed -rne 's / (TEXT_TO_BE_REPLACED) \ s + \ w + / \ 1 yyy / xxx'를 시도했지만 yyy가 있으면 문자열에서 yyy를 xxx로 바꿉니다. 제 경우에는 텍스트가 고정되어 있지 않습니다 ... 내가 가진 것은 TEXT_TO_BE_REPLACED입니다.
Rahul

유효한 sed 표현식이 아닙니다. sed로 하시겠습니까? 정규 표현식이 좋은 프로그래밍 언어는 대체 기능을 수행 할 수 있습니다 (하위 기능 검색). 그것은 당신이 sed 이해하는 것보다 쉬울 것입니다
Scharron

@Scharron 글쎄, 쉘 스크립트로 완료되었으므로 sed가 최선의 방법이라고 생각합니다.
Rahul

답변:


483

change 명령을 사용하여 전체 행을 바꾸고 -i플래그를 변경하여 제자리에서 변경할 수 있습니다. 예를 들어 GNU sed 사용 :

sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo

4
c \ 앞에 공백이 필요합니다. 이것을 추가하기 위해 방금 편집했습니다.
Marcus Downing

27
@MarcusDowning GNU sed에는 공간이 필요 하지 않습니다 . 원래 게시 된 그대로 작동합니다. 특정 sed에 공간이 필요한 경우, sed가 호환되지 않는 것을 기록하고 필요한 호출을 주석으로 추가하십시오. 그러나 허용되는 답변에서 작업 코드를 변경하지 마십시오.
Todd A. Jacobs

7
"This ..."텍스트 대신 변수를 어떻게 사용할 수 있습니까? $ variable로 바꾸면 내용이 아닌 변수 이름이 인쇄됩니다.
Steven

18
c\ 변수 바로 뒤에 올 때 문제가 있습니다 …c\$VAR…. 백 슬래시는 달러를 이스케이프합니다. 이 경우 I (Ubuntu 15.10에서 bash / sed)는 다음과 같이 작성해야합니다.…c\\$VAR…
Jan

6
맥에서는 : sed -i '' '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo; (첫 번째 매개 변수가 비어 있으면 파일 내에서 편집하고 그렇지 않으면 백업을 만듭니다)
AndreDurao

152

.*전체 라인을 교체하기 전후에 와일드 카드 ( ) 를 사용해야 합니다.

sed 's/.*TEXT_TO_BE_REPLACED.*/This line is removed by the admin./'

감사합니다, 내 일을했습니다 : sed 's /.* <expression>. * / <expression> SE_LABEL = ABC <expression> / g'MYR2.xml> test.txt
Nasri Najib

9
이것은 다음과 같이 -i 및 -e 플래그를 사용하는 것을 제외하고는 Mac OS X Yosemite에서 작동합니다.sed -i -e "s/.*search_string.*/Replacement_line/' file_being_searched.txt
Kent Bull

1
@KentJohnson 명령에 따옴표가 일치하지 않는다고 생각합니다.
HashHazard

@MBarnett 당신 말이 맞아요, 나는 두 개의 큰 따옴표가 있어야합니다.
Kent Bull

2
전체 정보 만 제공합니다. 그것을 -i
제자리에

20

몇 가지 이유로 받아 들인 대답이 효과가 없었습니다.

  • 내 버전의 sed는 -i길이가 0 인 것을 좋아하지 않습니다.
  • c\명령 의 구문 이 이상하고 작동하지 못했습니다.
  • 내 문제 중 일부가 이스케이프 처리되지 않은 슬래시에서 발생한다는 것을 몰랐습니다.

그래서 여기에 내가 생각해 낸 해결책이 대부분의 경우에 효과가 있다고 생각합니다.

function escape_slashes {
    sed 's/\//\\\//g' 
}

function change_line {
    local OLD_LINE_PATTERN=$1; shift
    local NEW_LINE=$1; shift
    local FILE=$1

    local NEW=$(echo "${NEW_LINE}" | escape_slashes)
    sed -i .bak '/'"${OLD_LINE_PATTERN}"'/s/.*/'"${NEW}"'/' "${FILE}"
    mv "${FILE}.bak" /tmp/
}

따라서 문제를 해결하기위한 샘플 사용법은 다음과 같습니다.

change_line "TEXT_TO_BE_REPLACED" "This line is removed by the admin." yourFile

18

위의 답변 :

sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo

대체 문자열 / 줄이 변수가 아닌 경우 제대로 작동합니다.

문제는 Redhat 5 \에서 c이스케이프 한 후 $입니다. 이중 \\은 작동하지 않았습니다 (적어도 Redhat 5에서는).

적중과 시험을 통해 교체 문자열 / 줄이 단 한 줄이면 \after after c가 중복되는 것을 발견했습니다 . 내가 사용하지 않은 그래서 \c, 하나의 교체 선으로 변수를 사용하고 기쁨이었다.

코드는 다음과 같습니다.

sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo

작은 따옴표 대신 큰 따옴표를 사용하십시오.


sed -i '/ TEXT_TO_BE_REPLACED / c' "$ VARIABLE" ''/ tmp / foo
Alistair McIntyre

4

지금까지 제공된 모든 답변은 대체 할 텍스트에 대해 알고 있다고 생각합니다. OP가 요청한 것이므로 의미가 있습니다. 대체 할 텍스트에 대해 아무것도 모른다고 가정하고 대체하고 싶지 않은 동일하거나 유사한 내용을 가진 파일에 별도의 줄이있을 수 있다고 가정합니다. 또한 교체 할 줄의 줄 번호를 알고 있다고 가정합니다.

다음 예제는 특정 줄 번호로 텍스트를 제거하거나 변경하는 방법을 보여줍니다.

# replace line 17 with some replacement text and make changes in file (-i switch)
# the "-i" switch indicates that we want to change the file. Leave it out if you'd
#   just like to see the potential changes output to the terminal window.
# "17s" indicates that we're searching line 17
# ".*" indicates that we want to change the text of the entire line
# "REPLACEMENT-TEXT" is the new text to put on that line
# "PATH-TO-FILE" tells us what file to operate on
sed -i '17s/.*/REPLACEMENT-TEXT/' PATH-TO-FILE

# replace specific text on line 3
sed -i '3s/TEXT-TO-REPLACE/REPLACEMENT-TEXT/'

3

구성 파일 조작

나는 skensell answer에서 영감을 얻은이 솔루션을 생각해 냈습니다.

configLine [searchPattern] [replaceLine] [filePath]

그것은 :

  • 존재하지 않는 경우 파일을 작성하십시오
  • searchPattern이 일치 하는 전체 줄 (모든 줄)을 바꿉니다.
  • 패턴을 찾을 수 없으면 파일 끝에 replaceLine 을 추가 하십시오 .

함수:

function configLine {
  local OLD_LINE_PATTERN=$1; shift
  local NEW_LINE=$1; shift
  local FILE=$1
  local NEW=$(echo "${NEW_LINE}" | sed 's/\//\\\//g')
  touch "${FILE}"
  sed -i '/'"${OLD_LINE_PATTERN}"'/{s/.*/'"${NEW}"'/;h};${x;/./{x;q100};x}' "${FILE}"
  if [[ $? -ne 100 ]] && [[ ${NEW_LINE} != '' ]]
  then
    echo "${NEW_LINE}" >> "${FILE}"
  fi
}

미친 종료 상태 마술은 https : //.com/a/12145797/1262663에서 가져옵니다.


2
bash-4.1$ new_db_host="DB_HOSTNAME=good replaced with 122.334.567.90"
bash-4.1$ 
bash-4.1$ sed -i "/DB_HOST/c $new_db_host" test4sed
vim test4sed
'
'
'
DB_HOSTNAME=good replaced with 122.334.567.90
'

잘 작동합니다


1

내 makefile에서 나는 이것을 사용한다 :

@sed -i '/.*Revision:.*/c\'"`svn info -R main.cpp | awk '/^Rev/'`"'' README.md

추신 : -i가 실제로 파일의 텍스트를 변경한다는 것을 잊지 마십시오 . 따라서 "개정"으로 정의한 패턴이 변경되면 패턴도 변경됩니다.

출력 예 :

John Doe가 작성한 Abc-Project

개정 : 1190

따라서 "개정 : 1190"패턴을 설정하면 "개정 :"으로 만 정의한 것과 동일하지 않습니다.


1
cat find_replace | while read pattern replacement ; do
sed -i "/${pattern}/c ${replacement}" file    
done 

find_replace 파일은 2 개의 열, c1과 일치하는 패턴, c2를 대체로 포함하고 sed 루프는 변수 1의 패턴 중 하나를 나타내는 각 행을 대체합니다.


아니요, 이것은 여러 가지로 잘못되었습니다. sed수행하려는 모든 대체를 포함하는 스크립트 파일로 한 번 실행하십시오 . sed -i동일한 파일에서 반복적으로 실행 하는 것은 끔찍한 반 패턴입니다.
tripleee

0

위의 것과 비슷합니다.

sed 's/[A-Za-z0-9]*TEXT_TO_BE_REPLACED.[A-Za-z0-9]*/This line is removed by the admin./'

3
변경은 FOO=TEXT_TO_BE_REPLACED할 수 FOO=This line ...있도록 사양을 충족하지 않습니다.
Jens

예 .. 우리의 요구 사항은 전체 줄을 '관리자가 제거합니다'로 바꾸는 것입니다. 우리가 키 패턴 'TEXT_TO_BE_REPLACED'를 찾았다면 위의 명령이 만족 스럽습니다. 나의 이해가 틀렸다면 나를 바로 잡으십시오. @Jens
Annapureddy Hari

@AnnapureddyHari 검색 문자열 앞뒤에 A-Za-z0-9 이외의 텍스트가 있으면이 답변이 작동하지 않습니다. Jens가 지적한 것처럼 등호가 있으면 실패합니다. "FOO ="부분은 그대로 유지됩니다. 전체 줄을 바꾸지 않았습니다. 이 코드는 파일에 무엇이 있을지 간략히 보여줍니다. 와일드 카드를 의미하는 경우 Thor의 답변에서 알 수 있듯이 와일드 카드를 넣어야합니다.
msouth 2016 년

0

아래 명령이 나를 위해 일하고 있습니다. 변수로 작업하는

sed -i "/\<$E\>/c $D" "$B"

그러나 새로운 요구 사항은 교체하는 동안 SKIP 주석 처리 된 # 줄로 시작하는 것입니다. 완전한 라인을 교체 할 때 주석이 달린 라인도 교체되며 중복 속성이 생깁니다. 누구든지 이것에 대한 해결책이 있다면 알려주십시오.
Ritesh Borkar

-1

나는 매우 자주 그냥 문자 그대로 인용 대체하는 것으로 사용되는 파일에서 데이터를 추출에 정규식을 사용 \"으로 //아무것도 :-)

cat file.csv | egrep '^\"([0-9]{1,3}\.[0-9]{1,3}\.)' | sed  s/\"//g  | cut -d, -f1 > list.txt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.