キーワードを使用して1つの大きな文字列から複数の文字列を抽出するBash awk / sed

キーワードを使用して1つの大きな文字列から複数の文字列を抽出する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」と次のスペースの間の文字列です。

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つの変数abおよびcは現在の入力レコード($0)に設定されます。その後、gsub()組み込み関数は正規表現を空の文字列("")に変更します。ここで、正規表現は2つのモードとを(/^.*Inventory for | .*$/交互に使用します。正規表現では置換が許可されます。行の先頭()からに変更します。これは、行の先頭から希望の最初の文字列までのすべての文字が削除されることを意味します。同様に、空白(最初の文字列の後ろ)から行末に変更します。また、2つの代替モードがあります。両方を変更します。/^.*Inventory for // .*$/|gsub()^Inventory for""""/^.*PID: |,.*$//^.*PID: //,.*$/""

次に空の文字列にsub()変更し、から11文字の文字列を取得します。/^.*SN: /substr(c,1,11)c

関連情報