【问题标题】:Stdout to file from which is reading content标准输出到正在读取内容的文件
【发布时间】:2012-03-11 14:14:38
【问题描述】:

当我想使用 Bash 修改文件时,我通常将 stdout 重定向到另一个文件,然后删除原始文件。有更快的方法吗?

例如:

cut -d':' -f2 FILE > FILE

这使我的源文件为空(它在写入之前清空文件然后开始读取)

我能做的只有:

cut -d':' -f2 FILE > FILE2
rm -f FILE
mv FILE2 FILE

有没有一种方法可以一步将(修改后的)输出重定向到原始文件?

【问题讨论】:

    标签: file bash io redirect io-redirection


    【解决方案1】:

    如果您安装Colin Watson's sponge utility(Colin 博客上的链接似乎已失效,但您可以将其作为Joey Hess' moreutils package 的一部分获取),您可以使用它来“吸收”输出,然后再将其转储到文件:

    cat FILE | cut -d':' -f2 | sponge FILE
    

    【讨论】:

    • 谢谢,我会尽快尝试,可能正是我想要的。
    • cat .zsh_history | sponge > .zsh_history 删除了一切。 sponge 应该在未指定文件时支持标准输出,但在这种情况下似乎出现故障。有什么想法吗?
    • @TonyH 问题是您使用了sponge > .zsh_history 而不是sponge .zsh_history> 表示 shell 重定向到输出文件,并且 shell always 在启动命令之前删除文件的内容(在这种情况下为sponge)。如果您将文件名作为参数传递给 sponge,它会一直等待,直到完成从其输入管道中读取所有内容,然后删除旧内容并写出新内容。
    • 感谢您解释 shell 的责任。我可以看到海绵的标准输出支持作为更长管道的一部分在哪里有用。
    【解决方案2】:

    恐怕我在 bash 中没有答案,但在 zsh 中很容易:

    cut -d':' -f2 =(cat FILE) > FILE
    

    =(...) 构造创建一个临时文件,其中包含上述程序的输出,该文件在包含它的命令完成后被删除。

    【讨论】:

    • 还是谢谢你。但是有没有办法用“shopt”之类的东西来做到这一点?
    【解决方案3】:

    恐怕在 bash 中没有方便的通用方法。问题是在运行任何命令之前,bash 打开FILE 进行输出,截断它,所以当cat 打开文件时,它看到的只是新的空文件。 sed 有一个 -i 选项来进行内联替换(它实际上使用临时文件),zsh=(...),如其​​他答案中所述,sort 手动检查输入和输出文件匹配(当使用 -o 时,正如我所提到的,使用 shell 重定向将在程序看到文件之前擦除文件),但 cut 和许多其他实用程序不匹配。您必须为这些使用临时文件。

    【讨论】:

      猜你喜欢
      • 2013-02-24
      • 2014-08-28
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2013-03-18
      • 1970-01-01
      • 2020-04-06
      • 2016-09-22
      相关资源
      最近更新 更多