연속적으로 반복되는 행 사이에 행을 삽입하는 방법은 무엇입니까?

연속적으로 반복되는 행 사이에 행을 삽입하는 방법은 무엇입니까?

가상 IP 주소를 추가하고 싶지만 두 개의 연속된 중복 행을 찾은 후에만 가능합니다.

저는 Linux 시스템에서 작업 중이며 이것이 제 입력 파일입니다.

  IP_Remote_Address
     Address : 192.168.1.1
  IP_Remote_Address
     Address : 192.168.1.2
  IP_Remote_Address
     Address : 192.168.1.3
  IP_Remote_Address
  IP_Remote_Address
     Address : 192.168.1.4
  IP_Remote_Address
     Address : 192.168.1.5
  IP_Remote_Address
     Address : 192.168.1.6
  IP_Remote_Address
     Address : 192.168.1.7
  IP_Remote_Address
  IP_Remote_Address
     Address : 192.168.1.8

내가 원하는 출력:

  IP_Remote_Address
     Address : 192.168.1.1
  IP_Remote_Address
     Address : 192.168.1.2
  IP_Remote_Address
     Address : 192.168.1.3
  IP_Remote_Address
     Address : NOT_FOUND
  IP_Remote_Address
     Address : 192.168.1.4
  IP_Remote_Address
     Address : 192.168.1.5
  IP_Remote_Address
     Address : 192.168.1.6
  IP_Remote_Address
     Address : 192.168.1.7
  IP_Remote_Address
     Address : NOT_FOUND
  IP_Remote Address
  Address : 192.168.1.8

다음 줄이 있지만 발견된 첫 번째 중복 항목만 대체합니다.

awk '{print $0; if((getline nl) > 0){ print ($0!="IP_Remote_Address" && $0 == nl)? nl=$0"INSERT_NOT_FOUND_ABOVE" : nl }}' file.txt

나중에 sed를 사용하여 문자열을 다음으로 바꿀 수 있습니다 INSERT_NOT_FOUND_ABOVE".

sed '/INSERT_NOT_FOUND_ABOVE/i Address : NOT_FOUND' file.txt > new_file.txt

내 유일한 문제는 모든 연속 중복을 감지하지 못하고 첫 번째 중복만 찾는다는 것입니다.

답변1

awk:

awk 'p==$0{print "     Address : NOT_FOUND"}{p=$0}1'

다소 순진한 솔루션입니다.

  • p==$0IF p == 현재 행
    • 그런 다음 인쇄not found
  • p=$0SET p = 현재 행
  • 1: 인쇄

연속된 중복 행을 처리합니다.


지적한대로@샌프란시스코문제의 댓글에는"아마 마지막 IP도 없어졌겠죠?"- UPS. 이것을 생각해야합니다.

그래서:

awk -v e='Address : NOT_FOUND' 'p==$0{print e}{p=$0}END{if($1 ~ "IP")print e}1'
  • 설정 e= 삽입할 텍스트
  • p==$0IF p == 현재 행
    • 그런 다음 변수를 인쇄하십시오.e
  • p=$0SET p = 현재 행
  • ENDe현재 줄에 다음이 포함되어 있는지 인쇄IP
  • 1: 인쇄

여기오류 문자열두 번 사용하므로 변수로 추가했습니다. (그리고 이 게시물에서는 가독성을 위해 잘렸습니다).

답변2

슬라이딩 창을 사용하여 GNU sed에서 이를 달성하는 한 가지 방법은 다음과 같습니다.

파싱.sed

# Handle last-line-error
$ { /IP/ s/$/\n   Address : NOT_FOUND/; }

# Always keep 2 lines in pattern-space
N

# If the lines are identical
/^([^\n]*)\n\1$/ { 

  # Add error text
  s/\n/\n   Address : NOT_FOUND\n/

  # Ensure we still only have 2 lines in pattern-space
  P
  s/[^\n]*\n//
}

# Print line 1 and delete it from pattern-space
P
D

다음은 세 가지 오류와 마지막 줄에 오류가 있는 수정된 테스트 텍스트입니다.

IP_Remote_Address
   Address : 192.168.1.1
IP_Remote_Address
   Address : 192.168.1.2
IP_Remote_Address
   Address : 192.168.1.3
IP_Remote_Address
IP_Remote_Address
IP_Remote_Address
IP_Remote_Address
   Address : 192.168.1.4
IP_Remote_Address
   Address : 192.168.1.5
IP_Remote_Address
   Address : 192.168.1.6
IP_Remote_Address
   Address : 192.168.1.7
IP_Remote_Address
IP_Remote_Address
   Address : 192.168.1.8
IP_Remote_Address

다음과 같이 실행하세요:

sed -Ef parse.sed infile

또는 한 줄로:

<infile sed -E '${/IP/ s/$/\n   Address : NOT_FOUND/};N;/^([^\n]*)\n\1$/{s/\n/\n   Address : NOT_FOUND\n/;P;s/[^\n]*\n//};P;D'

두 경우 모두 출력:

IP_Remote_Address
   Address : 192.168.1.1
IP_Remote_Address
   Address : 192.168.1.2
IP_Remote_Address
   Address : 192.168.1.3
IP_Remote_Address
   Address : NOT_FOUND
IP_Remote_Address
   Address : NOT_FOUND
IP_Remote_Address
   Address : NOT_FOUND
IP_Remote_Address
   Address : 192.168.1.4
IP_Remote_Address
   Address : 192.168.1.5
IP_Remote_Address
   Address : 192.168.1.6
IP_Remote_Address
   Address : 192.168.1.7
IP_Remote_Address
   Address : NOT_FOUND
IP_Remote_Address
   Address : 192.168.1.8
IP_Remote_Address
   Address : NOT_FOUND

답변3

확장된 정규식 모드에서 스트림 편집기 유틸리티 sed의 GNU 버전을 사용하십시오.

sed -Ee '
  x;1d;G
  ${/\n\s*IP_/ba;}
  /^(.*)\n\1$/{
    g;:a;p;c\
   Address : NOT_FOUND
    b
  }
  $!s/\n.*//
' file
  • 현재 라인은 저장 공간으로 들어가고, 이전 라인은 패턴 공간으로 들어갑니다.
  • 보류와 패턴 공간(즉, 이전 줄과 현재 줄)이 일치하는 경우 해당 줄 + 찾을 수 없는 줄을 인쇄합니다.
  • 마지막 줄은 /IP_/이고 찾을 수 없는 줄도 추가합니다.

관련 정보