次のファイルがあります。
S123456789^ABC|00||00||ZZ|MW00021C|ZZ|207RI0200X~LX|1~SV2|6666|FG>FG997|879.5|UN|4~DTP|472|D8|20150213~REF|6R|JHYU0003707988-1~LIN||N4|67202004164~LX|2~SV2|1234|FG>BP990|879.5|UN|12~DTP|472|D8|20170413~REF|6R|ABCD0003707988-1~LIN||N4|67202004908~
1
次のようにLX
、次のFG997
項目、次の項目を抽出してからLIN | | N4の横にある67202004164に抽出し、再び次の項目に抽出したいと思います。SV2|****|HC> ,879.5
4
UN,20150213
DTP|472|D8
2
LX
UNIXを使用してこれを達成するのに役立つ人はいますか?
このように解析する必要がある大容量ファイルがたくさんあります。
答え1
ファイル内のすべての行が同じ構造を持つ場合は、次のようにawkを使用できます。
$ awk -F"[|^~>]" -v OFS="," '{for (i=1;i<=NF;i++) print "Field",i,"---value:",$i}' <<<"$a"
#Output will be like:
Field,1,---value:,S123456789
Field,2,---value:,ABC
Field,3,---value:,00
Field,4,---value:,
Field,5,---value:,00
Field,6,---value:,
Field,7,---value:,ZZ
Field,8,---value:,MW00021C
Field,9,---value:,ZZ
Field,10,---value:,207RI0200X
Field,11,---value:,LX
Field,12,---value:,1
Field,13,---value:,SV2
Field,14,---value:,6666
Field,15,---value:,FG
Field,16,---value:,FG997
##More fields here - goes up to 51 ##
awkは-F
区切り文字(入力フィールドの区切り文字)を定義し、複数の文字を使用できます。
上記の例では、chars |
、、、を区切り文字として使用して、awkに行をより多くの部分に分割させます^
。 より多くの区切り文字を追加して、awk にフィールドをより多くの部分に分割させることができます。 PS:私の例の変数$aには質問テキストが含まれています。~
>
目的のフィールドを識別したら、次のスクリプトを作成して目的のフィールドを印刷できます。
$ awk -F"[|^~>]" -v OFS="," '{print $1,$12,$16,etc}' <<<"$a"
OFS は、印刷がフィールドを印刷するために使用する出力区切り文字を定義します。
awkで印刷する場合は、以下を参照してください。
*このような内容を印刷すると、'{print $1,$2}'
2つのフィールドはOFS(上記の例ではカンマ)で区切られます。 --> field1,field2
*awk などの内容を印刷すると、'{print $1 $2}'
2 つのフィールドが印刷されます。フィールドは接続されます - 1つの順番で、分離せずに - >field1field2
答え2
これは簡単ですPerl
。
perl -lne '
BEGIN{ $SKIP = qr/(?:[^|]+[|])/; $, = ","; }
print map { s/[~].*[|]/,/; y/|/,/; s/,?$//r; }
/
^[^^]+
| (?: LX [|] ) \K \d+
| (?: SV2 [|] \d+ [|] FG[>] )\K $SKIP{2}
| (?: UN [|] ) \K \d+ $SKIP{3} \d+
| (?: LIN [|][|] $SKIP ) \K \d+
/xg;
' yourfile
説明する:
-l
=> ORS=FS=\n
-n
=> dont print unless asked to
-e
=> 以下はPerl
コードです。$,
=>OFS
BEGIN
blockは、パイプで区切られたフィールドをスキップする正規表現を定義します。この正規表現は、パイプで区切られた2つのフィールド(時には3つまで)をスキップする必要があるときに複数回発生するためcan
(box
代わりに読みます)。ability
これはそれほど恐ろしく見えませんregex
。
/.../xgはすべての一致のリスト(\ Kの右側に表示される項目のみ)を返し、map {...}はいくつかの処理を実行し、結果を標準出力に出力します。
出力
S123456789,1,FG997,879.5,4,20150213,67202004164,2,BP990,879.5,12,20170413,67202004908