説明する:

説明する:

次のファイルがあります。

 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.54UN,20150213DTP|472|D82LX

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

BEGINblockは、パイプで区切られたフィールドをスキップする正規表現を定義します。この正規表現は、パイプで区切られた2つのフィールド(時には3つまで)をスキップする必要があるときに複数回発生するためcanbox代わりに読みます)。abilityこれはそれほど恐ろしく見えませんregex

/.../xgはすべての一致のリスト(\ Kの右側に表示される項目のみ)を返し、map {...}はいくつかの処理を実行し、結果を標準出力に出力します。

出力

S123456789,1,FG997,879.5,4,20150213,67202004164,2,BP990,879.5,12,20170413,67202004908

関連情報