キーワードに基づいて複数の部分文字列を抽出する方法を教えてください。区切り文字を使用したさまざまな方法で苦労しています。
私の入力:
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」と次のスペースの間にある
2番目の文字列は「PID:」とコンマの間の文字列です
3 番目の文字列は、「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
最初の 3 つの変数a
、b
およびがc
現在の入力レコード ( ) に設定されます$0
。次に、組み込み関数がgsub()
正規表現を空の文字列 ( ""
) に変更します。ここでの正規表現は、 との(/^.*Inventory for | .*$/
2 つのパターンを持つ交替を使用します。交替により、 を使用した正規表現の代替パターンが可能になります 。行頭 ( )から を使用すると、 は に変更されます。つまり、行頭から必要な最初の文字列までのすべての文字が削除されます。同様に、スペース (必要な最初の文字列の後) から行末までが に変更されます。同様に、にはと の 2 つの代替パターンがあります 。これらは両方とも に変更されます。/^.*Inventory for /
/ .*$/
|
gsub()
^
Inventory for
""
""
/^.*PID: |,.*$/
/^.*PID: /
/,.*$/
""
次に空の文字列にsub()
変更し、から 11 文字の文字列を取得します。/^.*SN: /
substr(c,1,11)
c