使用awk从记录中选择一些特定字段

时间:2014-04-26 19:57:59

标签: awk

假设我的文件只有一个包含100个字段的记录:

a1 a2 a3 a4 ... a100

其中所有a都是数字。是否有任何有效的方法来挑选所有小于某个数字的数字,例如300

4 个答案:

答案 0 :(得分:3)

您可以在awk

中更改记录选择器
awk -v RS=" " '$0<300' file

echo "100 200 300 400" | awk -v RS=" " '$0<300'
100
200

echo "100 200 300 400" | awk -v RS=" " -v ORS=" " '$0<300'
100 200 

echo "100 200 300 400 125" | awk '$0<300' RS=" " ORS=" "
100 200 125

为了彻底退出,我在最后添加了新行。领先于EdSteve:)

echo "100 200 300 400 150" | awk -v RS=" " -v ORS=" " '$0<300; END {print "\n"}'
100 200 150

如果在最后一个数字为真时没有您想要的额外空白行,请将\n添加到RS,但这会降低其可移植性。

echo "100 200 300 400 150" | awk -v RS=" |\n" -v ORS=" " '$0<300; END {print "\n"}'
100 200 150

答案 1 :(得分:3)

这个问题的难点在于产生一个解决方案,它不会在输出中添加前导或尾随空格和/或换行符,无论字段需要打印在哪个位置(某些字段在打印时会表现不同)第一个或最后一个字段)。

这样做:

$ echo "1 4 2 5 3 6" |
awk '{for (i=1;i<=NF;i++) if ($i<4) { printf "%s%s", ofs, $i; ofs=OFS } print "" }'
1 2 3

答案 2 :(得分:2)

awk '{for(i=1;i<=NF;i++) if($i<300) print $i;}' input.txt

输入:

100 200 300 400

输出:

100
200

要在一行中输出:

awk '{for(i=1;i<=NF;i++) if($i<300) {printf j==1?OFS$i:$i;j=1;}}' input.txt

答案 3 :(得分:2)

我在这里的首选解决方案是不使用AWK,而是在autosplit模式下使用Perl。 Perl允许您访问join()函数,使您的任务非常简单:

echo "1 2 3 4 5 6" | perl -lane 'print join (" ", grep { $_ < 4 } @F)'

结果:

1 2 3

优点:

  • 每行输入只写一次,而不是每行输入100次(或更多)写入,与此处的其他答案一样。
  • 避免使用记录或字段分隔符,导致或滞后的空白区域,换行符等。
  • 高度可读,可维护等等。

如果必须使用AWK,因为这是作业,您可以随时使用自己的join()功能。如果是这种情况,那么您可能对this一个感兴趣。