是否存在用于在CSV文件中删除列的命令行拼写?


32

具有以下内容的文件:

1111,2222,3333,4444
aaaa,bbbb,cccc,dddd

我试图得到一个与原始文件相等但缺少第n列的文件,例如n = 2(或者可能是3)

1111,2222,4444
aaaa,bbbb,dddd

或,对于n = 0(或可能为1)

2222,3333,4444
bbbb,cccc,dddd

实际文件的长度可以为千兆字节,具有数万列。

和以往一样,我怀疑命令行魔术师可以提供一个优雅的解决方案... :-)

在我实际的实际情况中,我需要删除2个第一列,这可以通过按顺序删除第一列两次来完成,但是我想概括一下会更有趣。


是否保证这些字段不包含,?(即,,仅用作字段分隔符。)
CVn 2012年

@MichaelKjörling,有一个更灵活的解决方案会很好,但是在我的情况下-是的:分隔符是,,并且它永远不会在字段内发生。
伊万(Ivan)

在那种情况下,斯科特的答案应该就是事实。
CVn 2012年

Answers:


47

我相信这是特定于GNU coreutils的:

$ cut --complement -f 3 -d, inputfile
1111,2222,4444
aaaa,bbbb,dddd

通常,您可以通过-f指定所需的字段,但是通过添加--complement可以自然地反转含义。从“人切”开始:

--complement
    complement the set of selected bytes, characters or fields

一个警告:如果任何列包含逗号,它将抛出cutt,因为cut不是与电子表格相同的CSV解析器。许多解析器对如何处理CSV中的转义逗号有不同的想法。对于简单的CSV情况,在命令行上,剪切仍然是可行的方法。


4
只要是简单的CSV文件,它就可以正常工作。如果其中任何一列是带逗号的字符串,则该列将被抛出cut,因为它不是CSV解析器。如果CSV字段的值中包含字段分隔符,则将其用引号引起来。顺便说一下,关于的主题cut-f取字段范围。cut -f, -d3-将输出第三个字段,删除前两个字段。
Alexios 2012年

2
您的意思是cut -d, -f3-
没用的2012年

@Alexios这是一个好点。我从未真正处理过“真实的” CSV,只涉及简单的子集。我将编辑我的答案以反映这一点。
Scott McClung 2012年

@没用:该死的,是的。这就是我所说的“切割型阅读障碍症”再次发作。感叹。斯科特:CSV文件是棘手的野兽。太多不同的子格式,其中有些甚至都不是C SV,但无论如何都通常称为子格式。
Alexios 2012年

这会将新的CSV打印到我的终端-如何获取它来覆盖输入(或者写到一个新文件,好像OP正在寻找其中一个)?
Max Ghenis 2014年

12

如果数据仅由逗号分隔的列组成:

cut -d , -f 1-2,4-

您也可以使用awk,但这有点尴尬,因为清除字段很容易,但是删除分隔符需要一些工作。如果没有空字段,那还不错:

awk -F , 'BEGIN {OFS=FS}  {$3=""; sub(",,", ","); print}'

如果您有实际的CSV(如果正确引用,逗号可以出现在字段中),则需要一个真正的CSV库

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.