我有几个巨大的 CSV 文件,我想交换其中的两个列名。
我愿意不是想要修改/复制/重写数据。
该操作非常便宜C
:fopen
文件,fgets
标题,fseek
或者rewind
,操纵标题(保持其长度)、fputs
新的标题、fclose
文件。
这也可以在ANSI Common Lisp
(交叉连接子系统,慢性淋巴细胞白血病或者胶粘剂):
(with-open-file (csv "foo.csv" :direction :io
:if-exists :overwrite)
(let ((header (read-line csv)))
(print header)
(file-position csv 0)
(write-line (string-upcase header) csv)
(file-position csv 0)
(read-line csv)))
并采取一瞬间(sed
需要几分钟因为它读取并重写整个文件,即使你告诉它只修改第一行,它也会忽略文件头大小这一关键信息不是改变)。
我如何使用“标准unix工具”(例如perl
)来做到这一点?
答案1
如果您不知道标题的长度,这head -n1
似乎是获取第一行的合理方法。
要将其就地写回到文件头部,可以使用 dd:
head -n1 file.csv | ./do-some-processing | dd of=file.csv bs=1 conv=notrunc
至关重要的conv=notrunc
是保持文件其余部分的完整性,并bs=1
在字节边界上停止。
答案2
对于这一点,我建议sed
您可以指定仅在第一行进行替换,例如1s/foo/bar/
:
$ cat file
col1,col2,col3
1,2,3
3,2,1
...
$ sed -e '1s/col1/tmp/' -e '1s/col3/col1/' -e '1s/tmp/col3/' file
col3,col2,col1
1,2,3
3,2,1
...
用于-i
将更改存储回文件:
$ sed -i -e '1s/col1/tmp/' -e '1s/col3/col1/' -e '1s/tmp/col3/' file
答案3
如果您想要的只是交换两个字,那么您所需要的只是就地重写几个字节。
对于命令行十六进制编辑器来说,这是一项简单的任务。
我推荐hexedit
使用这个工具来编辑一个 30 GB 的.csv
文件。打开/保存文件所花的时间可以忽略不计(不到一秒钟)。事实上,我的时间大部分都花在查找它的键盘快捷键... (TAB
切换到 ASCII 显示,Ctrl-X
保存并退出)。
答案4
或者也许“头部”文件以将第一行删除到单独的文件中。
然后更改标题文件并将两者合并在一起。