셸을 사용하여 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
?
답변1
글쎄, 나는 몇 가지 간단한 방법을 생각할 수 있지만 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
인해 Perl은 "단락 모드"에서 파일을 읽게 됩니다. 즉, "줄"\n\n
이 로 정의 되어\n
본질적으로 각 단락이 한 줄로 처리된다는 의미입니다. 따라서 교체는 개행 전체에서 일치합니다.앗
$ 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()
함수를 사용하여 이를 대체합니다.
답변2
전체 파일을 읽고 전역 교체를 수행합니다.
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
답변3
세 가지 다른 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///
대체 명령을 기반으로 구축되었습니다.
s/"[^"]*"\n<[^>]*>/other characters /
그들은 또한 마지막 줄에 주의를 기울이려고 노력합니다. 왜냐하면 sed
출력이 극단적인 경우에 달라지는 경향이 있기 때문입니다. 이것이 의미하는 바는 $!
마지막 줄이 아닌 모든 줄의 주소를 일치시키는 것입니다.!
$
또한 둘 다 ext 명령을 사용하여 N
패턴 공간의 \n
ewline 문자 에 다음 입력 행을 추가합니다. sed
한동안 이 문자를 사용해 온 사람 이라면 누구나 \n
ewline 문자에 의존하는 방법을 배울 것입니다. 왜냐하면 그것을 얻는 유일한 방법은 명시적으로 거기에 넣는 것이기 때문입니다.
세 가지 모두 조치를 취하기 전에 가능한 한 적은 입력을 읽으려고 노력합니다. 조치를 sed
취하기 전에 전체 입력 파일을 읽을 필요 없이 최대한 빨리 조치를 취합니다.
모두 그렇게 하지만 N
세 가지 모두 서로 다른 재귀 방법을 가지고 있습니다.
첫 번째 명령
첫 번째 명령은 매우 간단한 N;P;D
루프를 사용합니다. 이 세 가지 명령은 POSIX 호환 명령에 내장되어 있으며 sed
서로를 잘 보완합니다.
N
- 이전에 설명한 대로 삽입된 줄바꿈 구분 기호N
뒤의 패턴 공간 에 추가 입력 줄을 추가합니다.\n
P
-p
; 와 마찬가지로P
패턴 공간을 인쇄하지만 처음으로 나타나는\n
ewline 문자만 인쇄합니다. 따라서 다음 입력/명령이 제공됩니다.printf %s\\n one two | sed '$!N;P;d'
sed
P
인쇄만 가능하나. 그러나 ...D
- 마찬가지로d
;D
패턴 공간을 제거하고 또 다른 라인 루프를 시작합니다.같지 않은d
, 패턴 공간에서 처음으로 나타나는 ewlineD
만 삭제됩니다. ewline 문자 뒤의 패턴 공간에 더 많은 내용이 있는\n
경우 나머지 내용은 다음 줄 루프를 시작하는 데 사용됩니다. 예를 들어 이전 예에서 a를 바꾸면 다음도 인쇄됩니다.\n
sed
d
D
sed
P
하나그리고둘.
이 명령은 다음 줄에서만 반복됩니다.원하지 않는다s///
교체문을 일치시키세요 . 대체는 추가된 줄바꿈을 s///
제거하기 때문에 패턴 공간을 삭제할 때 아무것도 남지 않습니다.\n
N
sed
D
P
및/또는 을 선택적으로 적용하기 위해 테스트를 수행할 수 있지만 D
이 전략에 더 적합한 다른 명령이 있습니다. 일치하는 연속 행만 처리하도록 재귀가 구현되었기 때문입니다.부분연속 라인 시퀀스 일치에 대한 대체 규칙양쪽 끝대안이 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
ranch/ t
est 태그를 사용합니다.(Joseph R.의 답변도 이를 증명합니다.여기)특정 조건이 주어지면 재귀적으로 다시 돌아옵니다.
-e :n -e
- 이식 가능한 스크립트는 ewline 또는 새로운 인라인 실행 문을 사용하여sed
레이블 정의를 구분합니다.:
\n
-e
:n
- 라는 라벨을 정의합니다n
. 귀하는 언제든지bn
이 콘텐츠를 사용하거나 다시 돌아올 수 있습니다tn
.
tn
-t
est 명령은 지정된 레이블을 반환합니다.(또는 제공되지 않은 경우 현재 라인 사이클에 대한 스크립트를 종료합니다)s///
마지막 호출 이후 맞춤 태그나 교체 항목이 있으면 성공한t
것으로 간주됩니다.
이 명령에서는 일치하는 줄을 반복합니다. sed
패턴을 다음으로 성공적으로 바꾸면다른 역할, 라벨 sed
로 돌아가서 다시 시도하세요. 교체가 수행되지 않으면 :n
패턴 공간이 자동으로 인쇄되고 다음 라인 주기가 시작됩니다.s///
sed
이는 연속된 시퀀스를 더 잘 처리하는 경향이 있습니다. 마지막 것이 실패하면 다음을 인쇄하십시오.
first other characters other characters other characters line and so on
세 번째 주문
앞서 언급했듯이 여기의 논리는 이전 논리와 매우 유사하지만 테스트가 더 명확합니다.
/"$/bn
- 이것은sed
테스트입니다. ranch 명령은 해당 주소의 함수이기 때문에b
ewline이 추가되고 패턴 공간이 여전히 큰따옴표로 끝날 때까지 ranch는 반환sed
되지 않습니다b
.:n
\n
"
N
및 사이에 가능한 한 적은 작업을 수행합니다 b
. 이렇게 하면 sed
다음 줄이 규칙과 일치하지 않도록 하는 데 필요한 정확한 입력을 매우 빠르게 수집할 수 있습니다. 교체는 전역 플래그를 s///
사용한다는 점에서 다릅니다 g
. 따라서 필요한 모든 교체를 한 번에 수행합니다. 동일한 입력이 주어지면 이 명령의 출력은 이전 명령과 동일합니다.
답변4
이것은 변형입니다글렌의 대답연속해서 여러 번 발생하는 경우 작동합니다( sed
GNU에만 해당).
sed ':x /"line"/N;s/"line"\n<second>/other characters/;/"line"/bx' your_file
이것은 :x
지점에 대한 레이블일 뿐입니다. 기본적으로 이것이 하는 일은 대체된 줄을 확인하고 여전히 일치하는 경우 레이블 "line"
로 다시 분기하고 :x
(이것이 바로 그 일입니다 bx
) 버퍼에 다른 줄을 추가하고 처리를 시작하는 것입니다.