如何在 awk 中打印其中一列与某个值匹配的行?

如何在 awk 中打印其中一列与某个值匹配的行?

所以我有一个大文件,其中有几百万行逗号分隔值。

132.3,-23.3,1659614391.4174244,539.0,0,l_top
132.3,-23.1,1659614391.4174244,548.0,0,l_top
131.9,-22.900000000000002,1659614391.4174244,539.0,0,l_top
132.1,-22.700000000000003,1659614391.4174244,541.0,0,l_top
132.20000000000002,-22.5,1659614391.4174244,548.0,0,l_top
131.8,-22.200000000000003,1659614391.4174244,543.0,0,l_top
133.5,-22.3,1659614391.4174244,551.0,0,l_top
133.0,-22.1,1659614391.4174244,547.0,0,l_top
133.5,-21.900000000000002,1659614391.4174244,545.0,0,l_top
133.5,-21.700000000000003,1659614391.4174244,558.0,0,l_top

我尝试使用l_topawk 提取最后一列有价值的行,如下所示

awk -F ',' '{ if ($6 == "l_top") { print } else { exit }}' <file>

它什么也不打印。如果我在另一列上进行过滤,例如$5 == 0,则效果很好。也许行尾有什么问题?根据列值进行过滤的正确方法是什么?

答案1

这是因为exit意味着“退出程序”,所以你的程序将在第一行不以l_top.您可能正在寻找next

awk -F ',' '{ if ($6 == "l_top") { print } else { next }}' <file>

但是,当某些结果为 true 时 awk 中的默认操作是打印该行,因此您甚至不需要显式print.所有你需要的是:

awk -F, '$6 == "l_top"' file

要不就:

grep ',l_top$' file

答案2

特登的回答是您问题的解决方案,它还描述了为什么您的代码在不满足过滤条件的第一条记录处终止(简而言之:exit终止运行)。但是,如果您的 CSV 文件包含更复杂的字段(带有逗号和换行符等),则需要使用 CSV 感知工具来提取您要查找的记录。

这里使用的是磨坊主( mlr) 解析无头 CSV 文件file.csv,并提取最后一个字段为字符串的记录l_top

mlr --csv -N filter '$[NF] == "l_top"' file.csv

或者,要按数字访问第六列,

mlr --csv -N filter '$6 == "l_top"' file.csv

或者,如果您有标题,并且最后一个字段的标题是label(不是此处删除的-N):

mlr --csv filter '$label == "l_top"' file.csv

答案3

你有 DOS 行结尾,所以$6不是l_top,而是l_top\r,请参阅https://stackoverflow.com/questions/45772525/why-does-my-tool-output-overwrite-itself-and-how-do-i-fix-it

将命令更改为:

awk -F ',' '{ sub(/\r$/,""); if ($6 == "l_top") { print } else { exit }}' <file>

相关内容