7

Possible Duplicate:
How can I make iconv replace the input file with the converted output?
Can I read and write to the same file in Linux without overwriting it?

$ 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
$ 

Why does tr seem to output nothing to test.txt? I found this thread, but I don't really understand what is going on, and how to fix the problem.

(Also, the reason I'm not using sed is because I want to replace newlines with another character, and I don't think sed can operate on a non-line-by-line basis?)

2 Answers2

10

The problem is that you are reading and writing to/from the same file at the same time.

Your shell first setups the output redirection which results in an empty file (i.e. truncating it). Then it setups the input redirection and tr reads from an empty file.

You fix it using a temporary file, e.g:

$ tr 'a' 'z' < test.txt > temp.txt && mv temp.txt test.txt
maxschlepzig
  • 57,532
4

You can't redirect both from and to a file, at least not like that. The problem is that when the shell sets up the redirect-to part, it truncates the file. So tr tries to read from the file, its empty.

If your distro has a moreutils package, it contains a sponge program to resolve this problem: tr 'a' 'z' < test.txt | sponge test.txt will work.

Otherwise, you need to write your output to a temporary file, then use mv to overwrite the original file.

derobert
  • 109,670