tr ' ' '\t' < file 1<> file
Would replace every space character with a tab character.
Just to respond to people saying it's not safe:
The shell will open the file for reading on file descriptor 0, and for reading-and-writing on file descriptor 1. If any of those fail, it will bail out,
tr won't even be executed. If the redirections are successful,
tr is executed.
tr will read the file one block at a time, do the transliteration and output the modified block over the unmodified one.
In doing so, it will generally not need to allocate any space on disk. Exception to that would be if the file was sparse to start with, or file systems that implement copy-on-write. So errors for "no space available" are not likely.
Other errors may occur though like I/O error if the underneath disk is failing, or if the file system is on a block device that has been thinly provisioned (like a LVM snapshot), both conditions being rare and anyway probably going to involve bringing back a backup.
In any case, upon failure of the
write() system call,
tr should report an error and exit. Because its stdout is open in read-write mode, it will not be truncated. For the file to be truncated,
tr would have to explicitly call
truncate() on its standard output on exit which would not make sense.
What would happen though would be that the file would be partially transliterated (up to the point where
What I found out though is that the GNU
tr currently found on Debian sid amd64 has a bug in that it segfaults upon a failure of the
write() system call and output garbage on stdout (edit, now fixed since version 2.19-1 of the libc6 Debian package). That would actually corrupt the file (but again not truncate it).
tr ' ' '\t' < file > newfile && mv newfile file
would not replace
file unless the
newfile has been correctly created but has a number of issues associated with it:
- you need to make sure you don't clobber an already existing
newfile (think also symlinks)
- You need write access to the current directory
- you need additional storage space for that extra copy of the file
- you're losing the permissions, ownership, birth time, extended attributes... of the original file
- if the original file was a symlink, you're going to replace it with a regular.
tr ' ' '\t' < file 1<> file is safer than the commonly used
perl -pi -e 's/ /\t/g' because upon failure of
perl (like on disk full), you lose the original file and only get what
perl has managed to output so far.