使用sed格式化大文件

时间:2016-04-27 02:01:07

标签: bash unix awk sed

我有一个4.5GB的测试文件,我正在尝试格式化它。

首先,我尝试使用','替换标签,并使用"分隔每个列字段。

其次我用awk和sed格式化文件中的日期字段。

以下是我正在使用的内容:

格式化:

cat test_sample.csv | sed -e 's/"/""/g' | sed -e 's/\t/","/g' | sed -e 's/$/"/g' | sed -e 's/^/"/' > test_sample.csv

日期:

awk 'BEGIN{FS=OFS="\",\""} NR>1{cmd = "date -d \"" $10 "\" \"+%Y-%m-%d\"";cmd | getline out; $10=out; close("uuidgen")} 1' test_sample.csv > _report.tmp && mv _report.tmp test_sample.csv

这些命令对于小文件运行正常但是失败并且正在清除文件中的所有数据。

有人可以帮我格式化这个文件吗?

1 个答案:

答案 0 :(得分:5)

它们还清除小文件,因为重定向首先发生,因此文件被截断并保持为空。

考虑:

$ cat file.txt
A line of text
$ cat file.txt > file.txt
$ cat file.txt      # Empty!

为避免这种情况,您必须复制到临时文件 - sed中的-i选项为您执行此操作。它可以选择扩展:

sed -i.bak '...'

这解决了文件截断问题。

至于其他人:

  • 不要像这样多次调用sed:

    sed 's/pattern1/replacement1/' file | sed 's/pattern2/replacement2/' | ...
    

    这适用于通过完整文件的每个命令,使得进程慢得多。请改用:

    sed 's/pattern1/replacement1/;s/pattern2/replacement2/...'
    

    只处理一次文件。

  • 您不必使用cat来管道输入sed:sed将文件名作为参数,您可以避免使用Useless Use of cat。如果您将命令组合在一起并避免使用所有管道,请参阅下文。
  • 不要将sed和awk结合起来。根据经验,如果你在任何地方使用awk,你就不需要sed。

组合的单通道就地sed命令可能看起来像 1

sed -i 's/"/""/g;s/\t/","/g;s/$/"/;s/^/"/' test_sample.csv

将所有内容减少到单个awk命令(不再是单行友好,但绝对比组合sed和awk更快):

awk 'BEGIN { OFS="," }
NR > 1 {
    gsub(/"/, "\"\"")
    for (i = 1; i <= NF; ++i)
        $i = "\"" $i "\""
    cmd = "date -d \"" $10 "\" \"+%Y-%m-%d\""
    cmd | getline out
    $10 = out
    close("uuidgen")
    print
}' test_sample.csv > _report.tmp && mv _report.tmp test_sample.csv

1 在Mac OS中找到的BSD sed需要-i''