我有这个文件:
field1|field2|field3|f41;f42|f5
field1|field2|field3|f41|f5|
field1|field2|field3|f41;f42;f43|f5
我想解析它并获得:
field1|field2|field3|f41|f5
field1|field2|field3|f42|f5
...
简而言之,根据字段4中的半圆进行子分析。 我的awk脚本如下:
awk < myfile.txt -F\| '{
n=split($4,a,";");
print $1
for(i=0; ++i <= n;)
print $1"|"$2"|"$3"|"a[i]"|"$5"|";
}'
无论如何,对于没有以&#34; |&#34;我得到以下行的第一个字符消失! 例如,鉴于我得到的文件:
field1|field2|field3|f41|f5
ield1|field2|field3|f42|f5
我认为这是因为没有&#34; |&#34;在行尾。 有没有办法告诉awk考虑回车?
答案 0 :(得分:3)
for(i=0; ++i <= n;)
这样的古怪语法来编写你的for循环,因为它只会混淆你的代码(例如,我们需要先考虑i
第一次通过该循环是0还是1因为它没有明确说明)。只需将它们写成for (init;condition;increment)
:for(i=1;i <= n;i++)
。awk < file 'script'
,只需让awk打开文件awk 'script' file
,这样您就可以在脚本中访问FILENAME
。C
。print $1"|"$2"|"$3"|"a[i]"|"$5
,请按设计使用OFS:OFS="|";...;print $1,$2,$3,a[i],$5
。split($4,a,";")
,您应该使用split($4,a,/;/)
。所以第1步是重写你的脚本:
awk < myfile.txt -F\| '{
n=split($4,a,";");
print $1
for(i=0; ++i <= n;)
print $1"|"$2"|"$3"|"a[i]"|"$5"|";
}'
为:
awk '
BEGIN { FS=OFS="|" }
{
n=split($4,a,/;/)
print $1
for(i=1; i<=n; i++)
print $1, $2, $3, a[i], $5, ""
}
' myfile.txt
通过修复你的for
循环语法,我们现在可以清楚地看到你正在打印第一个字段两次,这是第一次在它自己的行上,所以我们可以立即改变那个:
$ awk '
BEGIN { FS=OFS="|" }
{
n=split($4,a,/;/)
for(i=1; i<=n; i++)
print $1, $2, $3, a[i], $5, ""
}
' myfile.txt
field1|field2|field3|f41|f5|
field1|field2|field3|f42|f5|
field1|field2|field3|f41|f5|
field1|field2|field3|f41|f5|
field1|field2|field3|f42|f5|
field1|field2|field3|f43|f5|
那么 - 你想要的是什么?不幸的是,您对所有输入行上的相同字段位置使用了相同的值,因此我们无法确定哪些输出行/字段来自哪些输入行/字段而您没有发布完整的预期输出,因此我们无法判断以上是否是预期的输出。它还不清楚你是否真的想要总是在每个输出行的末尾打印一个空字段,或者你是否真的想要硬编码输出字段的数量。
哦,如果你的输出中的字符消失了,因为你的输入文件中有控件-Ms或其他一些虚假的控制字符。使用cat -v
查看它们,dos2unix
或类似内容,如果它们是控件,则删除它们。
答案 1 :(得分:1)
这对你有用
awk -F"|" '{n=split($4,a,";"); for(i=1;i<=n;i++){ print $1FS$2FS$3FS a[i] FS $5}}' file.dat
field1|field2|field3|f41|f5
field1|field2|field3|f42|f5
field1|field2|field3|f41|f5
field1|field2|field3|f41|f5
field1|field2|field3|f42|f5
field1|field2|field3|f43|f5