
다음과 같은 블록의 모든 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
내 검색어( )와 일치 하는 경우 이 전체 데이터 블록을 추출하는 방법을 아는 사람이 있나요 P1-DIMMD1
?
답변1
다음은 태그 변수에 제공된 태그와 일치합니다.
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를 사용합니다.
command > dimm-output
wanted=P1-DIMMD1
ed -s dimm-output <<< $'/Location Tag: '"$wanted"$'\n?^ID.*SIZE.*TYPE\n.,/Configured Voltage/p\nq\n' | sed 1,2d
명령 문자열은 4개의 구분된 명령 ed
으로 구분됩니다 .\n
- 를 사용하여 "위치 태그: " 텍스트 뒤에 변수
/
값을 검색 합니다.$wanted
- 를 사용하여 뒤로 검색
?
: (줄 시작), "ID", 모든 것, "SIZE", 모든 것, "TYPE" - 해당 라인( )부터 ( ) "구성된 전압"과 일치하는 다음 라인을
.
거쳐 해당 라인( ) 을 인쇄합니다.,
p
- 종료 에드:
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