1

我有一个 16GB 的 CSV 文件,它是 ;-分隔的,并且字段总是被引用。我需要快速过滤掉第二个字段为空白的行。

"12345";"987";"..." # keep it
"67890";"";"..."    # omit it

如果这对性能很重要,前两个字段只是数字。

我想,那个 awk 可能是最高效的工具,但我似乎无法做到这一点。我试过这个,但它错误地省略了大多数行:

cat huge.csv | awk '/^"\d+";"\d/' > filtered.csv

当然不一定非要 awk;linux 和 OS X 上常见的任何命令行工具都可以。

4

3 回答 3

4

另一种解决方案只是使用

awk -F\" '$4' 

即,您的命令将是:

awk -F\" '$4' huge.csv > filtered.csv

这会将输入字段分隔符设置为"并检查第 4 个字段。如果它不为零,它会隐式打印该行。给出:

"12345";"987";"..." # keep it

用 GNU awk 3.1.6 测试

于 2012-08-14T22:27:43.857 回答
1

尝试这个:awk -v 'FS=;' '$2 != "\"\""' huge.csv > filtered.csv

解释:awk 将文件拆分为记录(默认:由换行符分隔),记录被拆分为记录(默认:由空格)。

-v选项允许在运行脚本之前设置任何 awk 变量,并且FS变量是特殊的内置变量,它指定字段分隔符的正则表达式。然后脚本只查看第二个字段(这是第二个 csv 字段),如果它非空,它(隐式)打印整个记录。

PS:即使你的脚本是非惯用的,它几乎是正确的:正则表达式应该是:/^"[^"]*";"\d/,所以当第一个字段是非数字时它匹配一行。

PPS:如果您需要通过给定的正则表达式过滤行,请使用 unix 实用程序grepgrep '^"[^"]*";"[0-9]' huge.csv > filtered.csv

于 2012-08-14T22:21:11.413 回答
1

除非您知道它;永远不会出现在任何引用的字段中,否则您不能为此使用 awk。但是,如果满足该标准,您可以执行以下操作:

awk '$2 != "\"\""' FS=\; huge.csv > filtered.csv

把它写成这样可能会更干净一些:

awk -F\; '$2 !~ /^""$/' huge.csv > filtered.csv
于 2012-08-14T22:21:36.267 回答