我正在学习 bash,但无法理解以下示例中的输出重定向出了什么问题:
我有一个名为 myfile.txt 的文件,其内容如下。
熟能生巧
我将使用tr
命令将P替换为p:
cat myfile.txt | tr P p
这就是我想要的,现在我要将结果放回原始文件中:
cat myfile.txt | tr P p > myfile.txt
但是执行完上面的命令后myfile.txt是空的……为什么会这样呢?
更新:
如果我将输出发送到另一个文件,那么它会按预期工作:
cat myfile.txt | tr P p > anotherfile.txt
Bash(和其他符合 POSIX 的 shell)遵循两个规则来解释这种行为:
重定向发生在命令运行之前。
如果文件存在,则在重定向到文件时将其截断(清空),如
> myfile.txt
.因此,因为存在
>
重定向,所以myinput.txt
get 的内容被丢弃并且cat
不打印任何内容,cat
退出并关闭管道并tr
关闭文件而不向其写入任何内容。命令开始的顺序并不是特别重要(并且不能保证,请参阅Gille's answer here)。但重要的是重定向发生在命令开始之前;那就是准备好每个命令的标准流,这就是最终导致空文件的原因。但是可以编辑相同的文件 工具,例如
sponge
,只是在这种特殊情况下不行。也可以看看:
使用: sort -o 而不是重定向。这样,您将能够写入同一个文件。
在我看来, cat 的使用意图不正确。通常 cat 用于组合文件,但也经常被误用于仅使用显示简单文件。
在您的情况下,我将按以下方式使用 tr 命令: