bash
쉘을 사용하면 다음과 같은 행이있는 파일에서
first "line"
<second>line and so on
나는 중 하나 개 이상 발생 대체하고자하는 "line"\n<second>
과를 other characters
각각의 시간을 가져 :
first other characters line and so on
둘 다 같은 특수 문자 문자열을 교체해야 그래서 "
및 <
및 개행 문자로.
다른 답변 사이에서 검색 한 후 sed
명령의 오른쪽 ( other characters
문자열) 에서 줄 바꿈을 수락 할 수 있지만 왼쪽 에는 줄 바꿈 을 사용할 수 없다는 것을 알았 습니다.
방법 (보다 간단 거기에 이 이 결과를 얻기 위해) sed
또는 grep
?
답변
세 가지 sed
명령 :
sed '$!N;s/"[^"]*"\n<[^>]*>/other characters /;P;D'
sed -e :n -e '$!N;s/"[^"]*"\n<[^>]*>/other characters /;tn'
sed -e :n -e '$!N;/"$/{$!bn' -e '};s/"[^"]*"\n<[^>]*>/other characters /g'
세 가지 모두 기본 s///
ubstitution 명령을 기반으로합니다 .
s/"[^"]*"\n<[^>]*>/other characters /
또한 sed
에지 라인 의 출력이 서로 다른 경향이 있기 때문에 마지막 라인을 다룰 때주의를 기울입니다 . 이것은 의미가 마지막 $!
이 !
아닌 모든 행과 일치하는 주소 $
입니다.
또한 모두 N
ext 명령을 사용하여 다음 입력 행을 추가하여 \n
ewline 문자 다음의 패턴 공간에 추가합니다 . sed
한동안 지낸 사람이라면 누구나 \n
ewline 특성 에 의존하는 법을 배웠을 것입니다. 왜냐하면 그것을 얻는 유일한 방법은 그것을 명시 적으로 넣는 것뿐이기 때문입니다.
세 가지 모두 조치를 취하기 전에 가능한 한 적은 양의 입력을 읽으려고 시도합니다 sed
. 그렇게하기 전에 전체 입력 파일에서 읽거나 읽을 필요가없는 한 빨리 작동합니다.
비록 그들이 모두했지만 N
, 세 가지 모두 재귀 방법이 다릅니다.
첫 번째 명령
첫 번째 명령은 매우 간단한 N;P;D
루프를 사용합니다. 이 세 명령은 모든 POSIX 호환에 내장되어 있으며 sed
서로 훌륭하게 보완합니다.
N
-이미 언급했듯이N
삽입 된\n
ewline 구분 기호 다음에 ext 입력 행을 패턴 공간에 추가합니다 .-
P
-같은p
; 그것은P
그러나 첫 번째 발생까지 -에 – 패턴 공간 rints\n
ewline 문자. 따라서 다음과 같은 입력 / 명령이 주어집니다.printf %s\\n one two | sed '$!N;P;d'
-
sed
P
단지 rints 하나 . 그러나 … D
-같은d
; 이D
패턴 공간을 eletes 다른 라인 사이클을 시작한다. 달리d
,D
단지까지 첫 번째 발생을 삭제\n
패턴 공간에서 ewline.\n
ewline 문자 다음에 패턴 공간이 더 있으면sed
남은 줄로 다음 줄주기를 시작합니다. 경우d
앞의 예에서이 교환되었다D
, 예를 들어,sed
것P
모두 RINT 하나 와 두 .
이 명령 은 ubstitution 문과 일치 하지 않는 행에 대해서만 반복됩니다 s///
. 때문에 s///
ubstitution가 제거 \n
로 추가 ewline을 N
때 나머지 결코 아무것도가 sed
D
eletes 패턴 공간을.
P
및 / 또는 D
선택적으로 적용하기 위해 테스트를 수행 할 수 있지만 해당 전략에 더 적합한 다른 명령이 있습니다. 대체 규칙의 일부 에만 일치하는 연속 행을 처리하기 위해 재귀가 구현되므로, ubstitution 의 양쪽 끝 과 일치하는 연속적인 행 시퀀스 s///
가 제대로 작동하지 않습니다.
이 입력이 주어지면 :
first "line"
<second>"line"
<second>"line"
<second>line and so on
… 인쇄 …
first other characters "line"
<second>other characters line and so on
그러나 처리합니다.
first "line"
second "line"
<second>line
… 괜찮아.
두 번째 명령
이 명령은 세 번째와 매우 유사합니다. 둘 다 :b
목장 / t
est 레이블을 사용하고 ( 여기서 Joeseph R.의 답변에 설명되어 있음 ) 특정 조건에서 다시 되풀이 됩니다.
-e :n -e
-이식 가능한sed
스크립트는 ewline 또는 새로운 인라인 xecution 문 으로:
레이블 정의를 구분합니다 .\n
-e
:n
-라는 레이블을 정의합니다n
.bn
또는 을 사용하여 언제든지 되돌릴 수 있습니다tn
.
tn
–t
지정된 라벨로 추정 명령이 리턴 (없음이 제공되지 않은 경우 또는, 현재 행주기위한 스크립트를 종료) 이있는 경우s///
ubstitution 레이블 중 하나가 정의 된 이후 또는가 마지막으로 시작된 이후라는t
성공적인 ESTS을.
이 명령에서 일치하는 행에 대해 재귀가 발생합니다. 경우 sed
성공적으로 패턴 대신 다른 문자 , sed
받는 돌아 :n
다시 레이블과 시도를. 경우 s///
ubstitution이 수행되지 않습니다 sed
autoprints에게 패턴 공간을 다음 행주기를 시작한다.
이것은 연속 시퀀스를 더 잘 처리하는 경향이 있습니다. 마지막 것이 실패하면 다음과 같이 인쇄됩니다.
first other characters other characters other characters line and so on
세 번째 명령
언급했듯이 여기의 논리는 마지막과 매우 유사하지만 테스트는 더 명확합니다.
/"$/bn
-이건sed
테스트 야 때문에b
목장 명령이 주소의 함수이며,sed
의지 만b
에 목장 다시:n
후\n
ewline이 추가 및 패턴 공간이 여전히으로 끝"
따옴표.
적게 사이에 다있다 N
하고 b
가능한 한 -이 방법으로 sed
매우 빠르게 다음 줄이 규칙과 일치하지 수 있도록 필요한만큼 입력으로 정확하게 수집 할 수 있습니다. s///
여기가 사용하는 것을 ubstitution의 다릅니다 g
은 한 번에 모든 필요한 교체 할 수 있도록하고 – lobal 플래그. 동일한 입력이 주어지면이 명령은 마지막과 동일하게 출력됩니다.
답변
글쎄, 나는 몇 가지 간단한 방법을 생각할 수 있지만 grep
(어쨌든 대체를하지 않는) 또는 sed
.
-
펄
교체하려면 각각 의 발생
"line"\n<second>
과other characters
사용을 :$ perl -00pe 's/"line"\n<second>/other characters /g' file first other characters line and so on
또는 여러 개의 연속 된 발생을
"line"\n<second>
하나로 처리하고 모든 단일 항목을 단일로 바꾸other characters
려면 다음을 사용하십시오.perl -00pe 's/(?:"line"\n<second>)+/other characters /g' file
예:
$ cat file first "line" <second>"line" <second>"line" <second>line and so on $ perl -00pe 's/(?:"line"\n<second>)+/other characters /g' file first other characters line and so on
는
-00
“선”에 의해 정의됨을 의미 ‘단락 모드 “에서 파일 읽기 펄 발생\n\n
않고\n
본질적으로, 각각 단락 선으로 처리된다. 따라서 대체는 개행에서 일치합니다. -
어 wk
$ awk -v RS="\n\n" -v ORS="" '{ sub(/"line"\n<second>/,"other characters ", $0) print; }' file first other characters line and so on
동일한 기본 개념으로, 레코드 구분 기호 (
RS
)를 설정하여\n\n
전체 파일을 슬러 핑 한 다음 출력 레코드 구분 기호를 아무 것도 설정하지 않은 경우 (다른 줄 바꿈이 인쇄 됨)sub()
함수를 사용하여 교체합니다.
답변
전체 파일을 읽고 전체 대체를 수행하십시오.
sed -n 'H; ${x; s/"line"\n<second>/other characters /g; p}' <<END
first "line"
<second> line followed by "line"
<second> and last
END
first other characters line followed by other characters and last
답변
다음 은 여러 번 연속적으로 발생하는 경우 작동하는 glenn의 답변 변형입니다 (GNU sed
에서만 작동 ).
sed ':x /"line"/N;s/"line"\n<second>/other characters/;/"line"/bx' your_file
이는 :x
분기를위한 레이블 일뿐입니다. 기본적으로 이것이하는 것은 대체 후 라인을 확인하고 여전히 일치 "line"
하는 경우 :x
레이블로 다시 분기 bx
되어 버퍼에 다른 라인을 추가하고 처리를 시작한다는 것입니다.