所以我有一个大文件,其中有几百万行逗号分隔值。
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_top
awk 提取最后一列有价值的行,如下所示
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>