키워드를 사용하여 하나의 큰 문자열에서 여러 문자열을 추출하는 Bash awk/sed

키워드를 사용하여 하나의 큰 문자열에서 여러 문자열을 추출하는 Bash awk/sed

키워드를 기반으로 여러 하위 문자열을 추출하는 방법을 알아내도록 도와주세요. 구분 기호를 사용하는 다양한 방법을 시도하는 데 어려움을 겪고 있습니다.

내 입력:

Inventory for 30844-ap01 NAME: AP1800 , DESCR: Cisco Aironet 1800 Series (IEEE 802.11ac) Access Point PID: AIR-AP1832I-E-K9, VID: V03, SN: KWC21420CKU
Inventory for ckh.hq-ap99 NAME: AP2700 , DESCR: Cisco Aironet 2700 Series (IEEE 802.11n) Access Point PID: AIR-CAP2702I-E-K9, VID: V03, SN: FCW2007N0ZQ
Inventory for AP0042.6843.ab78 NAME:  , DESCR:  PID: AIR-CAP1702I-E-K9, VID: V, SN: FCZ201622NY

원하는 출력:

30844-ap01 AIR-AP1832I-E-K9 KWC21420CKU
ckh.hq-ap99 AIR-CAP2702I-E-K9 FCW2007N0ZQ
AP0042.6843.ab78 AIR-CAP1702I-E-K9 FCZ201622NY

첫 번째 문자열은 "Inventory for"와 다음 공백 사이의 문자열입니다.

두 번째 문자열은 "PID:"와 쉼표 사이의 문자열입니다.

세 번째 문자열은 "SN:" 다음의 11자 문자열입니다.

답변1

모든 Unix 시스템의 모든 쉘에서 sed를 사용하십시오.

$ sed 's/Inventory for \([^ ]*\).*PID: \([^,]*\).*SN:/\1 \2/' file
30844-ap01 AIR-AP1832I-E-K9 KWC21420CKU
ckh.hq-ap99 AIR-CAP2702I-E-K9 FCW2007N0ZQ
AP0042.6843.ab78 AIR-CAP1702I-E-K9 FCZ201622NY

답변2

grep이러한 유형의 작업에 가장 적합한 도구는 다음과 같은 기능을 갖추고 있다고 생각합니다 PCRE.

grep -Po '(?<=Inventory for )[^ ]+|(?<=PID: )[^,]+|(?<=SN: ).{11}' data

그러나 이는 각 일치 항목을 별도의 줄에 인쇄해야 하는 단점이 있습니다.

30844-ap01
AIR-AP1832I-E-K9
KWC21420CKU
ckh.hq-ap99
AIR-CAP2702I-E-K9
FCW2007N0ZQ
AP0042.6843.ab78
AIR-CAP1702I-E-K9
FCZ201622NY

perl이제 다음으로 전환하여 동일한 작업을 수행해 보겠습니다 .

perl -lne ' $i = $& if /(?<=Inventory for )[^ ]+/; $p = $& if /(?<=PID: )[^,]+/ ; $s = $& if /(?<=SN: ).{11}/; print join " ", $i, $p, $s' data

인쇄:

30844-ap01 AIR-AP1832I-E-K9 KWC21420CKU
ckh.hq-ap99 AIR-CAP2702I-E-K9 FCW2007N0ZQ
AP0042.6843.ab78 AIR-CAP1702I-E-K9 FCZ201622NY

답변3

사용 gawk:

awk '{a=b=c=$0;
gsub(/^.*Inventory for | .*$/,"",a);
gsub(/^.*PID: |,.*$/, "",b);
sub(/^.*SN: /,"",c); c=substr(c,1,11);
print a,b,c}' input

처음 세 개의 변수 a, bc는 현재 입력 레코드( $0)로 설정됩니다. 그런 다음 내장 함수는 gsub()정규식을 빈 문자열( "")로 변경합니다. 여기서 정규 표현식은 두 가지 모드 와 를 (/^.*Inventory for | .*$/번갈아 사용합니다 . 정규 표현식에서는 교체가 허용됩니다 . 줄 시작 부분( ) 에서 로 변경합니다 . 이는 줄의 시작 부분부터 원하는 첫 번째 문자열까지의 모든 문자가 제거된다는 것을 의미합니다. 마찬가지로 공백(원하는 첫 번째 문자열 뒤)에서 줄 끝으로 변경합니다 . 또한 두 가지 대체 모드 가 있습니다 . 이 두 가지를 모두 로 변경합니다 ./^.*Inventory for // .*$/|gsub()^Inventory for""""/^.*PID: |,.*$//^.*PID: //,.*$/""

다음으로 빈 문자열로 sub()변경 하고 에서 11자 길이의 문자열을 가져옵니다 ./^.*SN: /substr(c,1,11)c

관련 정보