500줄의 텍스트가 포함된 파일이 있다고 가정해 보겠습니다.
one
two
three
four
five
six
seven
eight
nine
ten
.
.
.
five-hundred
일치 후 다섯 번째 줄을 특정 문자열로 바꾸려면 다음과 같이 하십시오.
sed '/two/{n;n;n;n;n;s/.*/MODIFIED/}' inputfile
산출:
one
two
three
four
five
six
MODIFIED
eight
nine
ten
.
.
.
five-hundred
그런데 경기가 끝난 후 60번 라인을 교체하고 싶다면 어떻게 해야 할까요? 나는 "n"을 60번 쓰고 싶지 않습니다.
x, h/H, g/G 및 범위를 사용해 보았지만 여전히 원하는 출력을 얻을 수 없습니다.
답변1
해결책 awk
:
awk '/two/{ n=NR+5 } NR==n{ sub(/.*/, "MODIFIED") }1' file
아니면 노선을 바꾸고 싶다면
awk '/two/{ n=NR+5 } NR==n{ $0="MODIFIED" }1' file
답변2
이러한 작업의 경우 검색 패턴이 오프셋 이전에 다시 나타나는 경우 어떻게 해야 할지 고려해야 할 수 있습니다.
awk -v offset=60 '
/two/ {x[NR + offset]}
NR in x {delete x[NR]; $0 = "MODIFIED"}
{print}'
위의 60번 라인이 포함될 때마다 라인 교체가 보장됩니다 two
.
답변3
/two/{
:loop
N
/\(\(.*\n\)\{5\}\).*/{
s//\1Modified/
b
}
b loop
}
저장 x.sed
하고 다음과 같이 실행하세요.
sed -f x.sed file
또는 GNU Sed를 사용하는 한 줄의 코드:
sed '/two/{:a;N;/\(\(.*\n\)\{5\}\).*/{s//\1Modified/;b;};ba;}' file
라인별 분석:
- 1-2: 일치하는 항목이 발견되면 반복을 시작합니다. 이 사이클에서는
- 3: 명령을 사용하여 패턴 공간에 라인을 추가합니다
N
. - 4: 5개의 줄바꿈이 있는 경우(기본 정규식은
\(.*\n\)\{5\}
-) 캡처 그룹에 넣고 마지막 줄(.*
)을 캡처되지 않은 상태로 둔 다음- 5: 전체 패턴 공간 * 을 캡처링 그룹으로 바꾸고 그 뒤에
Modified
라인을 추가합니다. - 6: 사이클을 깨십시오.
- 5: 전체 패턴 공간 * 을 캡처링 그룹으로 바꾸고 그 뒤에
- 8: 다시 말해 보세요
loop
.
- 3: 명령을 사용하여 패턴 공간에 라인을 추가합니다
* 빈 정규식 슬롯은 이전에 사용된 정규식과 동일하므로 5행은 과 동일합니다 s/\(\(.*\n\)\{5\}\).*/\1Modified/
.
덜 난해한 것은 Awk를 사용하는 것입니다.
awk '{c--};/two/{c=5};c==0{$0="Modified"};{print}' file
첫 번째는 감소하는 카운터 c
이며 모든 변수는 c
처음에 0이므로 일치하는 항목이 발견된 경우에만 양수가 됩니다.
보다 명시적인 접근 방식은 다음과 같습니다.
awk 'BEGIN{c=-1};/two/{c=5};c==0{$0="Modified"};{print};c>=0{c=c-1}' file
유용한 Sed 리소스:
답변4
모든 Unix 시스템의 모든 쉘에서 awk를 사용하여 이러한 일치가 5줄 범위 내에서 반복적으로 발생하지 않는다고 가정하고 전체 줄 문자열 일치를 수행합니다.
$ awk 'c&&!--c{$0="MODIFIED"} $0=="two"{c=5} 1' file
one
two
three
four
five
six
MODIFIED
eight
nine
ten
.
.
.
five-hundred