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