I've done this before, expect to mutate a file in place, something like $ tr '\t' ',' <file.txt >file.txt and well, clearly the > redirection truncates the file before < can read it;
Asked
Active
Viewed 39 times
0
ThorSummoner
- 4,312
- 6
- 30
- 47
-
I didn't see anything about how to operate on-place with < > or <> operators in that question, thanks for the link! Very helpful, but I did not find a useful or equivalent question/answer there to my specific question :bow: Specifically the answer https://unix.stackexchange.com/a/186126/61349 posted that there is basically no good way to do inplace mutations, either use a temporary file or a different file – ThorSummoner Jun 06 '18 at 20:46
-
2@ThorSummoner: You can't do what you are trying to do. – jesse_b Jun 06 '18 at 20:47
-
2[The second answer to that question](https://unix.stackexchange.com/a/186126/86440) should provide all the information you need. – Stephen Kitt Jun 06 '18 at 20:47
-
argh, that one ([Scott's answer there](https://unix.stackexchange.com/a/186126/170373)) is a good answer, but the question doesn't really indicate that subject at all... – ilkkachu Jun 06 '18 at 20:49
-
also: [Can I make `cut` change a file in place?](https://unix.stackexchange.com/q/5821/170373), [Modify a file without creating another file](https://unix.stackexchange.com/q/166064/170373), [Wait for stdout stream to finish and then add its contents to a file](https://unix.stackexchange.com/q/273999/170373) – ilkkachu Jun 06 '18 at 20:51
-
you can't avoid munging the file, because as soon as the command is run, the file descriptors are both created for your input and output, and the creation of the output fd effectively empties the input file, so that by the time the read() operation happens, the file is empty. you have to use a tool designed for in-place operations like `sed -i 's/\t/,/g' file.txt` – Tim Kennedy Jun 06 '18 at 20:55
-
"oh yeah just do": `(read I < file.txt; tr 'e' 'i' <<<"""$I""" > file.txt)`, "what could possibly go wrong" – ThorSummoner Jun 06 '18 at 21:04
-
@ThorSummoner, where did you pull that from? – ilkkachu Jun 06 '18 at 21:11
-
@ilkkachu authored it myself, I'm sure its vulnerable to arbitrary code execution and data loss... somehow- Bash always is <3, I wrote that mostly to point out how insane it is to memorize a solid work around for this design pattern without violating the original objective, reusing the original file inode – ThorSummoner Jun 06 '18 at 21:15
1 Answers
0
You cannot. The > redirect operator will create a new empty file as part of the pipeline. Tools (like sed --in-place) which appear to do so are creating a new file, writing to it, and moving the new file in place of the old one:
$ ls -i file; sed --in-place 's/foo/bar/' file; ls -i file
266110 file
262180 file
DopeGhoti
- 73,792
- 8
- 97
- 133
-
yeah, in effect you will always need some kind of [journal](https://en.wikipedia.org/wiki/Journal_(computing)) if you want to mutate the file contents in place, and it just so happens that if the working set fits in memory, and you have no power failures interruptions, you can get away with using the source file in memory as the effective journal :shrug: atleast thats how I put words to it – ThorSummoner Jun 06 '18 at 20:57