解释:

解释:

我有一个如下所示的文件:

 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 定义 print 将用于打印字段的输出分隔符。

关于 awk 中的打印,请注意:
* 当我们打印类似'{print $1,$2}'这样的内容时,这两个字段由 OFS 分隔(上例中为逗号) --> field1,field2
* 当我们打印类似'{print $1 $2}'awk 的内容时,会打印两个字段连接起来 - 一个接一个,不分隔之间 -->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 定义了一个正则表达式,它跳过一个管道分隔的字段。我们can(读为box而不是ability)这个正则表达式是因为当我们必须跳过 2 个管道分隔字段(有时甚至是 3 个)时,它会多次出现。这使得看起来regex不那么可怕。

/.../xg 返回所有匹配列表(仅那些出现在 \K 右侧的列表),然后 map { ... } 进行一些处理并将结果打印到标准输出。

输出

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

相关内容