【问题标题】:Linux - numerical sort then overwrite fileLinux - 数字排序然后覆盖文件
【发布时间】:2013-04-18 12:11:22
【问题描述】:

我有一个通用格式的 csv 文件

date,  
2013.04.04,
2013.04.04,
2012.04.02,
2013.02.01,
2013.04.05,
2013.04.02,

我运行的脚本会将数据添加到该文件中,这些数据不一定按日期顺序排列。如何将文件按日期顺序排序(忽略标题)并覆盖现有文件而不是写入 STDOUT

我用过awk

awk 'NR == 1; NR > 1 {print $0 | "sort -n"}' file > file_sorted
mv file_sorted file

有没有更有效的方法来做到这一点,而无需创建额外的文件和移动?

【问题讨论】:

    标签: linux sorting awk


    【解决方案1】:

    您可以执行以下操作:

    sort -n -o your_file your_file
    

    -o 定义了输出文件,是defined by POSIX,所以可以安全使用(没有损坏原始文件)。

    输出

    $ cat s
    date,  
    2013.04.04,
    2013.04.04,
    2012.04.02,
    2013.02.01,
    2013.04.05,
    2013.04.02,
    
    $ sort -n -o s s
    
    $ cat s
    date,  
    2012.04.02,
    2013.02.01,
    2013.04.02,
    2013.04.04,
    2013.04.04,
    2013.04.05,
    

    【讨论】:

    • 如果您能详细说明为什么这不会破坏文件,那就太好了(就像许多其他命令在读取和写入同一文件时所做的那样)。 -o 是否会像 sed -i 一样神奇地防止文件被破坏?对我来说,sort 似乎直到所有内容都被读取后才开始输出,因为最后一行可能总是排序输出中的第一行。我猜在--merge 模式下使用sort 时它可能会失败。如果我是对的,-o 与 shell 重定向 > 一样好。
    • @Socowi 好问题!这是defined by POSIX。您可以在this answer 阅读更多关于它的问题How to sort a file in-place
    • 哦,哇,谢谢你的链接。注释 »此文件可以与输入文件之一相同。« 在我的 man sort 中没有给出,所以我认为无法保证。
    • @Freedo 您的原件不会因错误而被截断并留下一个空文件
    【解决方案2】:

    请注意,如果脚本和排序同时运行,则存在竞争条件。

    如果文件头在数据之前排序,您可以使用 fedorqui 建议的解决方案,因为sort -o file file 是安全的(至少使用 GNU 排序,请参阅info sort)。

    awk 中运行sort 似乎有点复杂,另一种选择是使用headtail(假设是bash shell):

    { head -n1 file; tail -n+2 file | sort -n; } > file_sorted
    

    现在,关于替换现有文件。 AFAIK,您有两个选择,创建一个新文件并用您在问题中描述的新文件替换旧文件,或者您可以像这样使用moreutils 中的sponge

    { head -n1 file; tail -n+2 file | sort -n; } | sponge file
    

    请注意,sponge 仍会创建一个临时文件。

    【讨论】:

    • 谢谢我以前从未听说过海绵
    • @glennjackman:我在没有这些要求的 zsh 中进行测试。感谢您修复它。
    猜你喜欢
    • 2020-03-11
    • 2014-09-08
    • 1970-01-01
    • 2015-04-21
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多