일치 후 라인 N 교체

일치 후 라인 N 교체

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: 사이클을 깨십시오.
    • 8: 다시 말해 보세요 loop.

* 빈 정규식 슬롯은 이전에 사용된 정규식과 동일하므로 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

바라보다https://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern/17914105#17914105.

관련 정보