【发布时间】:2016-03-01 19:13:39
【问题描述】:
AWK 编程的新手。我有一个 file1 条目为:
15>000000513609200>000000513609200>B>I>0011>>238/PLMN/000100>File Ef141109.txt>0100-75607-16156-14 09-11-2014
15>000000513609200>000000513609200>B>I>0011>Danske Politi>238/PLMN/000200>>0100-75607-16156-14 09-11-2014
15>000050354428060>000050354428060>B>I>0011>Danske Politi>238/PLMN/000200>>4100-75607-01302-14 31-10-2014
我想写一个 awk 脚本,如果从第 3 个字段中减去的第 2 个字段是 0,那么它会打印第 2 个字段。否则,如果 (difference > 0),那么它会打印从第 2 个开始加 1 的所有中间数字在第 3 个字段结束的字段。不会有第三场小于第二场的情况。所以忽略那个条件。
我正在做的事情是:
awk 'NR > 2 { print p } { p = $0 }' file1 | awk -F">" '{if ($($3 - $2) == 0) print $2; else l = $($3 - $2); for(i=0;i<l;i++) print $2++; }'
((有人告诉我 awk 在语法上接近 C ))
但在我看来,字符串到数字或数字到字符串的转换并没有在正确的时间发生在正确的位置。不是应该由 AWK 自动处理吗?
我得到的输出:
513609200
513609201
513609200
这并不像预期的那样安静。一个明显的问题是它忽略了前面的 0。
请帮助我修改 AWK 脚本以获得所需的结果。
注意:
awk 'NR > 2 { print p } { p = $0 }' file1 只是删除我原始文件1 中的第一个也是最后一个条目。所以需要修复的部分是:
awk -F">" '{if ($($3 - $2) == 0) print $2; else l = $($3 - $2); for(i=0;i<l;i++) print $2++; }'
【问题讨论】:
-
@anubhava 如果第 3 和第 2 字段的差异为 0,则完全按原样打印第 2 字段。如果第 3 个字段大于第 2 个字段,则从第 2 个字段开始打印,每次递增 1,一直打印到第 3 个字段。数字应完全以 15 位格式打印(请参阅我的 fie 内容)
-
我会尽力理解您的解释,但显示准确的预期输出数据会更清楚。
-
else后面有 2 个语句,但没有大括号。不管怎样,for语句正在执行。 -
是的,awk 是
close to C in terms of syntax,但这绝对不意味着你可以假设它是 C 语法,因为如果你这样做了,即使你设法编写了一个在那里执行并产生预期输出的脚本如果您学会了如何以惯用方式使用 awk,那么几乎肯定会是一种更好的方法。获取 Arnold RObbins 所著的《Effective Awk Programming, 4th Edition》一书。 -
@glennjackman 抱歉,刚刚重新访问了您的评论。无需将
v更改为$v。我现在知道区别了。但仍然存在一个问题。无论 AWK 对变量v执行什么数字处理,它都会自动删除前导 0。但我想要前导 0,因为它是最后一个字符串。如何执行此操作。我的意思是:输入:1,004402146016260,004402146016300输出:1,4402146016260,1,4402146016270.....,1,4402146016300预期输出:1,004402146016260,1,004402146016270.....,1,004402146016300。请注意,可以有任意数量的前导 0,而不仅仅是 2。
标签: regex linux bash shell awk