将 tr stdout 重定向到文件

将 tr stdout 重定向到文件

可能的重复:
如何使 iconv 用转换后的输出替换输入文件?
我可以在 Linux 中读写同一个文件而不覆盖它吗?

$ cat test.txt 
This is a test file.
$ tr 'a' 'z' < test.txt 
This is z test file.
$ tr 'a' 'z' < test.txt > test.txt
$ cat test.txt
$ 

为什么 tr 似乎没有向 test.txt 输出任何内容?我发现这个线程,但我不太明白发生了什么事,以及如何解决问题。

(另外,我不使用 sed 的原因是因为我想用另一个字符替换换行符,并且我不认为 sed 可以在非逐行基础上操作?)

答案1

问题是您同时从同一个文件读取和写入。

您的 shell 首先设置输出重定向,这会产生一个空文件(即截断它)。然后它设置输入重定向并tr从空文件中读取。

您可以使用临时文件修复它,例如:

$ tr 'a' 'z' < test.txt > temp.txt && mv temp.txt test.txt

答案2

你不能同时从一个文件重定向到一个文件,至少不能像那样重定向。问题是,当 shell 设置重定向到部分时,它会截断该文件。所以 tr 尝试从文件中读取,它是空的。

如果您的发行版有一个moreutils软件包,它包含一个sponge解决此问题的程序:tr 'a' 'z' < test.txt | sponge test.txt可以工作。

否则,您需要将输出写入临时文件,然后用于mv覆盖原始文件。

相关内容