다음과 같은 특정 줄이있는 텍스트 파일이 있습니다.
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
'
잘 작동합니다