Sed: 텍스트 파일에서 다음 줄 \n 기호를 바꾸는 방법은 무엇입니까?

Sed: 텍스트 파일에서 다음 줄 \n 기호를 바꾸는 방법은 무엇입니까?

오류를 수정하고 다음 구조의 XML 파일에서 두 번째 태그를 두 번째 태그 </time>로 바꿔야 합니다.</tags>

<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>

각 항목에 2개의 닫는 태그가 있으므로 sed를 사용하여 이 작업을 수행하려고 합니다 . </time>아이디어는 </time><geo>로 바꾸는 것입니다 </tags><geo>.

그런데 중간에 다음 줄 기호가 있어서 사용하고 있는데 \n작동이 않되네요.

sed 's/time>\n<geo>/tags>\n<geo>/g' old.xml > new.xml

답변1

Sed는 입력을 한 줄씩 처리하므로 입력에 개행 문자가 자발적으로 나타나지 않습니다. 당신이 할 수 있는 일은 ;로 끝나는 줄을 일시 중지하고 </time다음 줄이 로 시작하면 <geo>이전 줄을 바꾸는 것입니다. (이것은 sed에서 "공간 예약"을 사용하여 가능하지만 공간을 보존해야 할 경우 awk 또는 perl로 전환하는 것이 좋습니다.)

그러나 예제 입력에 따라 로 시작하는 줄로 </time>변경할 수 있습니다 .</tags><tags>

sed -e '/^<tags>/ s!</time>$!</tags>!'

답변2

문제를 쉽게 해결할 수 있는 다른 방법이 있을 수도 있지만 질문에 대한 대답은 간단합니다. sed기본적으로 하나의 행은 2개의 버퍼에서 한 번에 처리됩니다. 하나는 행 주기에 걸쳐 지속되는 h오래된 공간이라고 하며, 다른 하나는 주기마다 적어도 한 번 플러시되는 패턴 공간이라고 합니다. 후자는 모든 편집이 수행되는 곳입니다. .

Lookahead 기능은 두 가지 방법 중 하나로 얻을 수 있습니다. 즉, 버퍼를 교환하고 비교하는 명령을 더 잘 사용하기 위해 오래된 라인을 저장하고 라인 사이클보다 뒤처지게 할 수 있습니다. 여기에는 [hH]old, [gG]et, e x변경(각각 저장, 복사 및 교체) 과 같은 명령 기본 요소가 포함됩니다. 소문자 형식은 덮어쓰고 대문자 형식은 대상 버퍼에 추가됩니다.

또는 각 사이클에서 읽은 만큼의 입력 라인을 항상 삭제하는 지속적인 편집 알고리즘에 향후 라인을 넣을 수 있습니다. 여기서는 후자를 선호합니다. 특히 명령을 sed사용하면 매우 간단하고 효율적이기 때문입니다 N;P;D.

샘플 데이터를 사용한 데모는 다음과 같습니다.

sed '$!N;s/ime\(>\n<geo\)/ags\1/;P;D
'  <<\IN
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
IN

Next, Print 및 Delete는 소문자와 마찬가지로 n;p;d각각 다음 입력 줄을 가져와 인쇄하고 패턴 공간에서 삭제합니다. 소문자와 다름N(상황이 조금 다른 경우), 이 세 가지는 패턴 공간 전체보다는 개행 경계에서 작동합니다.

  • N다음 입력 행은 패턴 공간의 ewline 문자 뒤에 추가됩니다 \n.
  • P\n패턴 공간에서 처음으로 나타나는 ewline 문자 만 인쇄됩니다.
  • D\n현재 루프에 대한 스크립트를 종료하기 전에 패턴 공간에서 처음으로 나타나는 ewline만 제거되고 패턴 공간의 나머지 내용과 함께 대기열에 추가됩니다. 또는 제거 작업 후에 아무 것도 없으면 다음 줄은 평소대로 대기열에 들어가세요.

sed이 세 가지가 함께 작동하여 파일의 편집 창을 매우 간단하고 효율적으로 확장할 수 있습니다. sed파일을 슬라이딩하고 각 주기는 스크립트 작성자의 지시에 따라 계속 제거하고 보충하는 일련의 줄에서 가장 오래된 줄만 인쇄합니다 sed. 라인 사이클.

그리고 다음 라인에 대한 미리보기는 쉽게 확장 가능합니다. 전체 스크립트에 4줄 패턴 공간 창이 포함되도록 하려면 다음을 수행할 수 있습니다.

sed -e '1{N;N' -e '};N;...;P;D'

...또는 어쩌면 더 유용할 수도 있습니다...

sed -e ':next
    $!{/\(.*\n\)\{3\}/!{
        N;b next' -e '}
    };...cmds...;P;D'

... sed입력 라인만 그려지고 다른 명령이 실행되기 전에 충분할 때까지 계속 그렇게 합니다. 패턴 공간에 ewline 문자가 3개 미만이고 \n현재 라인이 마지막 라인이 아닌 경우입니다. 이는 후속 명령의 편집 내용에 관계없이 발생합니다.

답변3

이 질문에 문학적으로 답해 보세요.

나는 약간의 치트를 사용하여 이 문제를 해결했습니다(편집할 텍스트가 여러 줄에 걸쳐 있음).

cat input.txt | tr '\n' '@' | sed -e 's/txt@iam@interestedin/iaminterested@intxt/g' | tr '@' '\n' > output.txt

확인해야 할 유일한 것은 개행 문자를 대체할 문자가 입력에 이미 존재하지 않는다는 것입니다.

관련 정보