파일의 특정 패턴에 헤더 추가

파일의 특정 패턴에 헤더 추가

Linux의 여러 위치에 헤더를 추가해야 하는 파일이 있습니다. "헤더"는 파일이므로 첫 번째 줄에만 추가할 수 있습니다. 하지만 이제는 특히 새 IP 주소를 찾기 전에 여러 위치에 동일한 헤더를 추가하고 싶습니다. 실제로 헤더가 있는 파일은 필요하지 않습니다. 모든 출력을 얻은 후 awk 또는 sed를 통해 텍스트를 추가하기만 하면 됩니다.

헤더는 새 IP 주소를 찾은 직후에 삽입해야 합니다.

목록은 가변적입니다. 예를 들어 ip 192.168.10.10에는 3개의 항목이 있지만 더 있을 수 있습니다. 예를 들어 ip 192.168.10.33에는 2개의 항목이 있지만 더 있을 수 있습니다. 포트는 기본적으로 정렬됩니다. IP 주소는 정렬되지 않고 그룹화됩니다.

출력은 다음과 같습니다.

192.168.10.10    1/1/2
192.168.10.10    1/1/3
192.168.10.10    1/1/4
192.168.10.33    1/1/2
192.168.10.33    1/1/6
192.168.10.20    1/1/6
192.168.10.20    1/1/7
192.168.10.20    1/1/10
192.168.10.20    1/1/18

출력이 다음과 같기를 원합니다.

SWITCH ID        PORT    
192.168.10.10    1/1/2
192.168.10.10    1/1/3
192.168.10.10    1/1/4

SWITCH ID        PORT              
192.168.10.33    1/1/2
192.168.10.33    1/1/6

SWITCH ID        PORT
192.168.10.20    1/1/6
192.168.10.20    1/1/7
192.168.10.20    1/1/10
192.168.10.20    1/1/18

답변1

이것은 헤더를 추가하는 다소 긴 awk 스크립트입니다.

NR==1 {
  print "SWITCH ID        PORT"
  print $0
  prev=$1
  next
}
$1!=prev {
  print ""
  print "SWITCH ID        PORT"
  print $0
  prev=$1
  next
}
$1==prev {
  print $0
}

파일로 저장하세요. 예를 들어addheader.awk

이렇게 전화하세요

awk -f addheader.awk inputfile

아니면 이렇게

commandproducinginput | awk -f addheader.awk

스크립트 설명

awk의 작동 원리는 대략 다음과 같습니다.

for every line of input
  for every rule
    if condition is true
      execute code block

"규칙"은 조건과 코드 블록의 쌍입니다.

위 코드의 규칙 예

NR==1 {
  print "SWITCH ID        PORT"
  print $0
  prev=$1
  next
}

이것이 NR==1조건입니다. 중괄호 안의 부분은 {...}코드 블록입니다.

NR줄 번호(정확히 말하면 레코드 번호)를 포함하는 awk 특정 변수입니다. 따라서 NR==1첫 번째 줄만 정확합니다.

첫 번째 줄에서는 헤더 행을 인쇄합니다. 그런 다음 실제 줄( $0현재 줄의 awk 변수)을 인쇄합니다. 그런 다음 이 줄의 IP 주소( $1현재 줄의 첫 번째 필드의 awk 변수)를 기억하세요. 그런 다음 awk가 다른 규칙을 고려하지 않도록 다음 줄로 직접 이동한다고 말합니다. 루프에서 벗어나는 것을 next상상할 수 있습니다 .breakfor every rule

$1!=prev현재 IP 주소가 이전 주소와 일치하지 않으면 다음 규칙의 조건이 true입니다. 이 경우 빈 줄을 인쇄합니다. 그러면 제목이 있습니다. 그런 다음 라인 자체가 있습니다. 그런 다음 이 새 IP 주소를 기억해 두십시오. 그런 다음 다음 줄로 이동하십시오.

마지막 규칙은 "Default Case"입니다. IP 주소가 이전과 동일하면 해당 행을 그대로 인쇄합니다.

next위의 규칙은 if else if 체인을 효과적으로 형성합니다.

의사코드에서는 대략 다음과 같습니다.

for every line:
  if is first line:
    print header then line
  else if IP adress is different than previous:
    print empty line then header then line
  else if IP adress is same to previous:
    print line

보너스:

다음 변형은 동일합니다.

마지막 코드 블록을 생략합니다.

NR==1 {
  print "SWITCH ID        PORT"
  print $0
  prev=$1
  next
}
$1!=prev {
  print ""
  print "SWITCH ID        PORT"
  print $0
  prev=$1
  next
}
$1==prev

코드 블록이 누락된 경우 기본 동작은 해당 행을 있는 그대로 인쇄하는 것입니다.

또는 조건을 생략하고 코드 블록을 유지합니다.

NR==1 {
  print "SWITCH ID        PORT"
  print $0
  prev=$1
  next
}
$1!=prev {
  print ""
  print "SWITCH ID        PORT"
  print $0
  prev=$1
  next
}
{
  print $0
}

조건이 누락된 경우 이는 암시적으로 참입니다. 이는 next위의 규칙이 if else if 체인을 효과적으로 형성하기 때문에 가능합니다 . 마지막 규칙은 마지막 else와 유사하므로 조건이 필요하지 않습니다.

규칙 재정렬

$1==prev
NR==1 {
  print "SWITCH ID        PORT"
  print $0
  prev=$1
}
$1!=prev {
  print ""
  print "SWITCH ID        PORT"
  print $0
  prev=$1
}

이렇게 생략할 수는 있지만 next내 취향에는 가독성이 떨어집니다.

공통 코드를 함수로 추출

func common() {
  print "SWITCH ID        PORT"
  print $0
  prev=$1
  next
}
NR==1 {
  common()
}
$1!=prev {
  print ""
  common()
}
$1==prev

모든 변수는 awk에서 전역 변수입니다.

관련 정보