Questo è assolutamente possibile, devi solo assicurarti che nel momento in cui scrivi l'output, lo stai scrivendo su un file diverso. Questo può essere fatto rimuovendo il file dopo aver aperto un descrittore di file su di esso, ma prima di scriverlo:
exec 3<file ; rm file; COMMAND <&3 >file ; exec 3>&-
Oppure riga per riga, per capirlo meglio:
exec 3<file # open a file descriptor reading 'file'
rm file # remove file (but fd3 will still point to the removed file)
COMMAND <&3 >file # run command, with the removed file as input
exec 3>&- # close the file descriptor
È ancora una cosa rischiosa da fare, perché se COMMAND non funziona correttamente, perderai il contenuto del file. Ciò può essere mitigato ripristinando il file se COMMAND restituisce un codice di uscita diverso da zero:
exec 3<file ; rm file; COMMAND <&3 >file || cat <&3 >file ; exec 3>&-
Possiamo anche definire una funzione di shell per renderlo più facile da usare:
# Usage: replace FILE COMMAND
replace() { exec 3<$1 ; rm $1; ${@:2} <&3 >$1 || cat <&3 >$1 ; exec 3>&- }
Esempio :
$ echo aaa > test
$ replace test tr a b
$ cat test
bbb
Inoltre, nota che questo manterrà una copia completa del file originale (fino alla chiusura del terzo descrittore di file). Se stai usando Linux e il file su cui stai elaborando è troppo grande per stare due volte sul disco, puoi controllare questo script che reindirizzerà il file al comando specificato blocco per blocco mentre annulli l'allocazione del già elaborato blocchi. Come sempre, leggi le avvertenze nella pagina di utilizzo.