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
플래그를 지정하여 변경합니다.들어 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 '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
대체 문자열/라인이 변수가 아닌 경우 정상적으로 작동합니다.
문제는 레드햇 5에서\
에 c
합니다.$
블더.\\
(적어도 Redhat 5에서는) 작동하지 않았습니다.
뺑소니와 재판을 통해, 저는 그것이\
에 c
대체 문자열/줄이 한 줄만 있는 경우 중복됩니다.그래서 사용하지 않았습니다.\
에 c
변수를 하나의 대체 라인으로 사용했고 그것은 기쁨이었습니다.
코드는 다음과 같습니다.
sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo
작은따옴표 대신 큰따옴표를 사용합니다.
승인된 답변은 몇 가지 이유로 저에게 효과가 없었습니다.
- 내 버전의 sed는 좋아하지 않습니다.
-i
확장자를 합니다. - 의
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)
# FIX: No space after the option i.
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
지금까지 제공된 모든 답변은 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/'
구성 파일 조작용
저는 스켄셀 답변에서 영감을 받아 이 솔루션을 생각해냈습니다.
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://stackoverflow.com/a/12145797/1262663 에서 나옵니다.
makefile에서 다음을 사용합니다.
@sed -i '/.*Revision:.*/c\'"`svn info -R main.cpp | awk '/^Rev/'`"'' README.md
PS: -i가 실제로 파일의 텍스트를 변경한다는 것을 잊지 마십시오.따라서 "수정"으로 정의한 패턴이 변경되면 바꿀 패턴도 변경됩니다.
출력 예:
ABC-프로젝트: John Doe 작성
개정판: 1190
그래서 패턴 "Revision: 1190"을 설정하면 "Revision:"으로만 정의한 것과 분명히 다릅니다.
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
'
그것은 잘 작동합니다.
GNUism에와 같은 하지 않고 것.-i
변수 또는 매개변 없이또는수 없이c
바꿈 : 줄 바꿈:
sed '/TEXT_TO_BE_REPLACED/c\
This line is removed by the admin.
' infile > tmpfile && mv tmpfile infile
다음(POSIX 호환) 형식의 명령입니다.
c\
text
text
는 하나 이상의 줄로 구성될 수 있으며, 대체할 줄 바꿈의 일부가 되어야 합니다.
c\
line1\
line2
s/x/y/
s/x/y/
두 후 입니다.
line1
line2
cat find_replace | while read pattern replacement ; do
sed -i "/${pattern}/c ${replacement}" file
done
find_replace file에는 일치할 패턴이 있는 c1, 치환이 있는 c2, 변수 1의 패턴 중 하나를 포함하는 각 행이 sed 루프에 의해 대체되는 2개의 열이 포함됩니다.
지정된 문자열을 포함하는 전체 줄을 해당 줄의 내용으로 바꾸려면
텍스트 파일:
Row: 0 last_time_contacted=0, display_name=Mozart, _id=100, phonebook_bucket_alt=2
Row: 1 last_time_contacted=0, display_name=Bach, _id=101, phonebook_bucket_alt=2
단일 문자열:
$ sed 's/.* display_name=\([[:alpha:]]\+\).*/\1/'
output:
100
101
공백으로 구분된 여러 문자열:
$ sed 's/.* display_name=\([[:alpha:]]\+\).* _id=\([[:digit:]]\+\).*/\1 \2/'
output:
Mozart 100
Bach 101
요구사항에 맞게 정규식 조정
[:alpha] 및 [:digit:]는 문자 클래스 및 대괄호 식입니다.
이것은 저에게 효과가 있었습니다.
sed -i <extension> 's/.*<Line to be replaced>.*/<New line to be added>/'
예는 다음과 같습니다.
sed -i .bak -e '7s/.*version.*/ version = "4.33.0"/'
-i
교체 후 백업 파일의 확장명입니다.이경우, 은것그입니다..bak
.-e
sed 본대. 이이경, 그은것입니다.'7s/.*version.*/ version = "4.33.0"/'
하려면 SED 파일을 합니다.-f
s
바꿀 파일의 줄 번호입니다.이경우, 은것그입니다.7s
그 말은 7호선을 의미합니다.
참고:
합니다.sed
그러면 할 수 있습니다.grep
명령의 시작 부분까지:
grep -rl --exclude-dir=<directory-to-exclude> --include=\*<Files to include> "<Line to be replaced>" ./ | sed -i <extension> 's/.*<Line to be replaced>.*/<New line to be added>/'
이 질문은 다음을 사용하여 해결책을 묻는 것입니다.sed
하지만 그것이 어려운 요구사항이 아니라면 더 현명한 선택이 될 수도 있습니다.
받아들여진 대답은 다음과 같습니다.sed -i
파일 in-place를 하지만, 파을제자교것설으명만지하로는체하서에,-i
실제로 그렇게 하지 않고 대신 동등한 것을 합니다.sed pattern file > tmp; mv tmp file
소유권 및 모드 유지.이것은 많은 상황에서 이상적이지 않습니다.으로 일적으실권않습다니지하장반행을로다않니▁in습을 실행하는 것을 추천하지 않습니다.sed -i
자동화 과정의 일부로서 비연속적으로 -- 그것은 길이를 알 수 없는 퓨즈로 폭탄을 설치하는 것과 같습니다.조만간 누군가에게 폭발할 것입니다.
실제로 파일을 "in place"로 편집하고 패턴과 일치하는 줄을 다른 내용으로 바꾸려면 실제 텍스트 편집기를 사용하는 것이 좋습니다.이렇게 하면 됩니다.ed
표준 텍스트 편집기
printf '%s\n' '/TEXT_TO_BE_REPLACED/' d i 'This line is removed by the admin' . w q | \
ed -s /tmp/foo > /dev/null
이는 질문이 원하는 첫 번째 일치 선만 대체한다는 점에 유의하십시오.이것은 대부분의 다른 답변들과 실질적인 차이입니다.
그 단점은 차치하고, 몇 가지 장점이 있습니다.ed
1파운드가 sed
:
- 추가 작업 없이 하나 이상의 행으로 일치를 바꿀 수 있습니다.
- 대체 텍스트는 보호하기 위해 탈출할 필요 없이 임의로 복잡할 수 있습니다.
- 가장 중요한 것은 원본 파일이 열리고 수정 및 저장된다는 것입니다.사본이 만들어지지 않았습니다.
작동 방식
작동 방식:
- 첫형식을 합니다. 는 사실상 각 인수가 출력 printf로 합니다. 효과적으로 printf에 대한 각 인수가 출력 라인이 되어 모든 것이 전송됩니다.
ed
스트딘에서 - 첫 번째 줄은 정규식 패턴 일치로, "현재 줄"의 개념이 일치하는 첫 번째 줄로 이동합니다(일치하지 않는 경우 현재 줄은 파일의 마지막 줄로 설정됨).
- 은 다은음입니다.
d
시하는령명을 지시하는 .ed
현재 행 전체를 삭제합니다. - 에 그다은음▁the가 있습니다.
i
을 명령어.ed
모드 모드; - 그런 다음 입력된 모든 후속 라인이 현재 라인(또는 내장된 새 라인이 있는 경우 추가 라인)에 기록됩니다. 변수(예, 즉변를수있다니습)를 확장할 수 있습니다.
"$foo"
줄이 여기에 여러 줄이 포함되어 있으며 모든 줄이 삽입됩니다. - 는 다음과 같이 종료됩니다.
ed
는 로으 구된선봅니로 을 보여줍니다..
- 그
w
명령어는 파일의 내용을 디스크에 씁니다. - 그자리의
q
지휘를 그만두다 - 그
ed
에는 " 이주니다집어"가 됩니다.-s
합니다. - 은 편할파인제니다에 .
ed
, - 그리고 마지막으로 정규식과 일치하는 선이 인쇄되지 않도록 stdout을 버립니다.
일부 유닉스 계열 시스템은 (부적절하게) 다음 버전 없이 배송될 수 있습니다.ed
설치되었지만 여전히 배송될 수 있습니다.ex
만약 그렇다면 당신은 그것을 대신 사용할 수 있습니다.에 다면이 ,vim
하지만 아닙니다ex
또는ed
사용할 수 있습니다.vim -e
대신.표준만 있는 경우vi
하지만 아닙니다ex
또는ed
시스템 관리자에게 불만을 제기합니다.
그것은 위의 것과 유사합니다.
sed 's/[A-Za-z0-9]*TEXT_TO_BE_REPLACED.[A-Za-z0-9]*/This line is removed by the admin./'
아래 명령이 저에게 효과가 있습니다.변수로 작동하는 것은
sed -i "/\<$E\>/c $D" "$B"
많습니다. 의 따옴표를 사용했습니다. 저는 문자 그대로의 인용문을 대체하기 위해 방금 사용했습니다.\"
와 함께//
:-) ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ :-)
cat file.csv | egrep '^\"([0-9]{1,3}\.[0-9]{1,3}\.)' | sed s/\"//g | cut -d, -f1 > list.txt
언급URL : https://stackoverflow.com/questions/11245144/replace-whole-line-containing-a-string-using-sed
'programing' 카테고리의 다른 글
Postgres에서 두 필드의 MIN()을 얻으려면 어떻게 해야 합니까? (0) | 2023.05.13 |
---|---|
Postgre 사용 안 함SQL 외부 키의 마이그레이션 확인 (0) | 2023.05.13 |
.xls 파일을 읽고 쓸 수 있는 .NET Excel 라이브러리 (0) | 2023.05.08 |
스위프트 언어로 된 추상 클래스 (0) | 2023.05.08 |
단어 목록에 대한 PostgreSQL 와일드카드 LIKE (0) | 2023.05.08 |