일치하는 경우 여러 행 추출

일치하는 경우 여러 행 추출

다음과 같이 블록의 모든 DIMM 슬롯에 대한 정보를 출력하는 명령이 있습니다.

ID    SIZE TYPE
44    105  SMB_TYPE_MEMDEVICE (type 17) (memory device)

  Manufacturer: NO DIMM
  Serial Number: NO DIMM
  Asset Tag: NO DIMM
  Location Tag: P1-DIMMD1
  Part Number: NO DIMM

  Physical Memory Array: 43
  Memory Error Data: Not Supported
  Total Width: 0 bits
  Data Width: 0 bits
  Size: Not Populated
  Form Factor: 9 (DIMM)
  Set: None
  Rank: Unknown
  Memory Type: 2 (unknown)
  Flags: 0x4
        SMB_MDF_UNKNOWN (unknown)
  Speed: Unknown
  Configured Speed: Unknown
  Device Locator: P1-DIMMD1
  Bank Locator: P0_Node1_Channel0_Dimm0
  Minimum Voltage: 1.20V
  Maximum Voltage: 1.20V
  Configured Voltage: 1.20V

이러한 블록은 ID SIZE TYPE헤더로 시작하고 구성된 전압 정보로 끝납니다. 이 명령은 각 DIMM에 대해 이러한 데이터 블록 중 하나를 출력합니다. 각 블록은 빈 줄로 구분됩니다.


이 필드를 기반으로 특정 DIMM 슬롯에 대한 정보 덩어리를 얻을 수 있기를 원 Location Tag하지만 어떻게 해야 할지 모르겠습니다. 이것이 가능하다고 확신 하지만 일치 항목 이나 일치 항목 앞에 있는 줄을 awk인쇄하는 방법만 알면 됩니다.awk '/P1-DIMMD1/'awk '/P1-DIMMD1/ {print a}{a=$0}'

Location Tag내 search() 와 일치하는 경우 전체 데이터 덩어리를 추출하는 방법을 아는 사람이 있습니까 P1-DIMMD1?

답변1

다음은 label 변수에 지정된 레이블과 일치합니다.

awk -v tag=P1-DIMMD1 '/ID    SIZE TYPE/ { block = $0; output = 0; next } { block = block "\n" $0 } /Location Tag/ { output = ($0 ~ tag) } /Configured Voltage/ && output { print block }'

AWK 스크립트는 다음과 같습니다.

/ID    SIZE TYPE/ {
  block = $0
  output = 0
  next
}

{ block = block "\n" $0 }

/Location Tag/ { output = ($0 ~ tag) }

/Configured Voltage/ && output { print block }

우리는 변수에 청크를 축적 block하고 프로세스 중에 올바른 레이블이 보이면 청크의 끝에 도달했을 때 이를 출력합니다.

답변2

당신은 할 수에드를 사용하세요...그리고세드, 친구!

당신은해야합니다생각하다그러나 ed는 파이프라인의 일부가 아닌 파일에서 작업하기를 원하므로 이를 처리하려면 ed를 사용하십시오.

  1. command > dimm-output
  2. wanted=P1-DIMMD1
  3. ed -s dimm-output <<< $'/Location Tag: '"$wanted"$'\n?^ID.*SIZE.*TYPE\n.,/Configured Voltage/p\nq\n' | sed 1,2d

명령 문자열은 4개의 개별 명령 ed으로 구분됩니다 .\n

  1. "위치 태그:" 텍스트와 변수 /값을 사용하여 앞으로 검색합니다.$wanted
  2. 사용, 역방향 검색 ?패턴: (줄의 시작), "ID", any, "SIZE", any, "TYPE"
  3. 이 라인( .)부터 ( ,)까지 "구성 전압"과 일치하는 다음 라인을 인쇄합니다( p).
  4. 수정 종료:q

ed는 검색 시 일치하는 줄을 자동으로 인쇄하므로 sed여기서는 이 두 줄을 삭제합니다.

답변3

@Stephen Kitts의 훌륭한 답변에서 영감을 받아 지정된 시작 및 끝 패턴이 있을 때 블록 일치를 수행하는 보다 일반적인 스크립트를 작성했습니다.

#!/usr/bin/awk -f
BEGIN {
    pstart=ARGV[1];
    pstop=ARGV[2];
    pmatch=ARGV[3];
    ARGV[1]=ARGV[4];
    ARGC=2;
}
$0 ~ pstart { block = $0; output = 0; next }
{ block = block "\n" $0 }
$0 ~ pmatch { output = 1 }
$0 ~ pstop && output { print block; output = 0 }

용법:match_block START END MATCH [FILE]

./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1' f

또는

command | ./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1'

awk직접 스크립트를 작성하도록 제안해 주셔서 감사합니다 . 내 원래 쉘 스크립트는 다음과 같습니다

#!/bin/sh

[ -z "$4" ] && file="-" || file="$4"

awk \
  -v BLOCKSTART_PATTERN="$1" \
  -v BLOCKEND_PATTERN="$2" \
  -v BLOCKMATCH_PATTERN="$3" \
  '
  $0 ~ BLOCKSTART_PATTERN { block = $0; output = 0; next }
  { block = block "\n" $0 }
  $0 ~ BLOCKMATCH_PATTERN { output = 1 }
  $0 ~ BLOCKEND_PATTERN && output { print block; output = 0 }
  ' "$file"

용법: match_block START END MATCH [FILE].
파일을 생략하면 stdin해당 파일이 사용됩니다.

귀하의 경우:

command | ./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1'

또는

./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1' file

관련 정보