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

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

sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext

위의 전체 줄을

This line is removed by the admin.

검색 키워드는 TEXT_TO_BE_REPLACED

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



답변

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

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


답변

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

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


답변

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

  • 내 버전의 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


답변

위의 답변 :

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

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


답변

지금까지 제공된 모든 답변은 대체 할 텍스트에 대해 알고 있다고 생각합니다. 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/'


답변

구성 파일 조작

나는 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에서 가져옵니다.


답변

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
'

잘 작동합니다