sed 또는 ex를 사용하여 블록(여러 줄의 코드)을 새로운 텍스트 블록(코드)으로 바꾸는 방법은 무엇입니까?

sed 또는 ex를 사용하여 블록(여러 줄의 코드)을 새로운 텍스트 블록(코드)으로 바꾸는 방법은 무엇입니까?

파일(셸 스크립트 코드)의 텍스트 덩어리를 다른 텍스트 덩어리로 바꿔야 합니다.

나에게 인상깊었던 점은sed를 사용하여 여러 줄 문자열을 바꾸는 방법은 무엇입니까?응답자 안타크그리고다중 라인 교체응답자브루스 에디거

하지만 그것들을 사용하는데 약간의 문제가 있습니다.

  1. 안타크그의 답변에서 이미 언급했듯이 1h;2,$H;$!d;g;전체 file()을 버퍼로 스트리밍하는 것은 메모리에 과부하가 걸리기 때문에 대용량 파일에는 권장되지 않습니다.

  2. sed블록 외부의 텍스트를 변경하지 않고 그대로 두기 위해 블록 기능과 함께 사용할 수 있다는 것을 알고 있습니다 . 이 기능을 사용하고 싶습니다. 하지만 내가 사용한다면,

    sed -i '/marker1/,/marker2/s/.*/new text (code)/' filename
    

각 스트림에 대해 반복적으로 새 텍스트(코드)를 삽입합니다. 그래서 제안과 같은 것을 사용하여 시각적 블록을 스트림으로 스트리밍해야 했습니다.안타크이전에는 블록(전체 파일이 아님)용이었습니다.

  1. 말한 바와 같이브루스 에디거ex점으로 시작하는 추가 기능을 시도하는 것이 가능 하지만 새 텍스트(코드)에는 점으로 시작하는 줄이 포함되어 있으며 이는 추가 구문에서 점으로 간주될 수 있습니다. 이런 경우에는 어떻게 사용해야 하나요?a.

  2. ex"줄 수 dd"는 여러 줄을 제거할 수 있지만, /marker1/과 /marker2/ 사이에 고정되지 않은(변경) 줄 수의 블록이 있고 새 텍스트(코드)로 바꾸려는 경우 어떻게 해야 합니까?

답변1

나는 사용하는 것이 좋습니다hange 명령(기본적으로엘레테 플러스보류(추가는 원하는 범위의 마지막 행에만 적용되지만).

sed -i '/marker1/,/marker2/c\
New text 1\
New text 2' filename

sed여기서는 내부 편집( )을 위해 GNU 구문이 사용됩니다 -i. 그렇지 않으면 명령은 c표준적이고 이식 가능합니다. GNU sed지원:

sed '/marker1/,/marker2/cNew text 1\
New text 2' filename

비표준 확장으로.

줄 바꿈 및 백슬래시 문자는 대체 텍스트에서 이스케이프 처리(백슬래시 사용)해야 합니다.

답변2

GNU sed 사용

일치하는 줄에서 시작하여 일치하는 줄 3까지 계속되는 줄을 바꾸려면 다음을 수행하십시오 .5New Code

$ seq 8 | sed '/3/,/5/{/5/ s/.*/New Code/; t; d}'
1
2
New Code
6
7
8

range 에 있는 행의 경우 /3/,/5/행이 일치하는지 5(즉, 그룹의 마지막 행인지) 테스트하고, 그렇다면 insert 로 바꿉니다 New Code. 대체가 이루어지면 이 명령은 sed에게 명령 끝( t이 경우 New Code인쇄됨 )으로 점프하라고 지시합니다. 그렇지 않은 경우 이 d명령은 sed에게 해당 행을 삭제하라고 지시합니다.

다른 모든 줄은 정상적으로 인쇄됩니다.

파일을 현재 위치에서 변경하려면 -i다음 옵션을 사용할 수 있습니다.

sed -i.bak '/3/,/5/{/5/ s/.*/New Code/; t; d}' file

awk를 사용하세요

awk를 사용하여 동일한 작업을 수행합니다.

$ seq 8 | awk '/3/,/5/{if (!f)print "New Code"; f=1; next}; 1'
1
2
New Code
6
7
8

awk 명령은 범위 내의 행을 특별히 처리합니다 /3/,/5/. 범위에 있는 줄의 경우 f0인지(즉, !f참이면) 테스트하고, 그렇다면 인쇄 New Code하고 1로 설정한 f다음 나머지 명령을 건너뛰고 해당 next줄로 이동합니다.

범위를 벗어난 줄의 경우 /3/,/5/점프가 발생하지 않고 1줄이 인쇄됩니다. 좀 더 구체적으로 말하면 1조건이다. 10이 아니기 때문에 조건은 true로 평가됩니다. 조건과 관련된 작업이 없으므로 기본 작업, 즉 라인을 인쇄하는 작업이 수행됩니다. 이는 1print-the-line의 약자입니다.

파일을 제자리에서 변경하려면 GNU 4.1 이상에서 이 -i inplace옵션을 사용할 수 있습니다 .awk

awk -i inplace '/3/,/5/{if (!f)print "New Code"; f=1; next} 1' file

답변3

위의 논의를 바탕으로 해결책을 찾았습니다.ex

seq 15 > test1.txt
ex test1.txt << EOEX
/^7/,/^9/c
abcd
123
.xyz
hfr4
.
w!
q
EOEX
cat test1.txt

위에 주어진

1
2
3
4
5
6
abcd
123
.xyz
hfr4
10
11
12
13
14
15

감사해요g 남성변경 명령을 이해하고 요점을 명확히하겠습니다. sed둘 다 ex거의 유사한 변경 명령 ​​구문을 공유합니다(삭제 명령, 추가 명령 등에 적용됨).

관련 정보