Editar arquivos de texto sem um arquivo temporário é uma má idéia e geralmente não é feito em scripts Unix. Isso requer a regravação de todo o arquivo, ou pelo menos a parte do sufixo que é afetada por uma edição. Se a gravação for interrompida, o arquivo está corrompido.
Naturalmente, fazemos isso todos os dias com os editores de texto: armazenamos os arquivos na memória e os sobregravamos no disco quando salvamos. As diferenças são que todos os editores decentes mantêm pelo menos um backup, a menos que esse recurso seja explicitamente desabilitado (e que seja um arquivo extra, não aceitável para você, presumivelmente) e que os editores sejam interativos: se um save falhar por algum motivo completo, falha do sistema, qualquer que seja) uma pessoa sabe disso. Nos casos em que não é um travamento, o editor ainda está em execução e tem o arquivo na memória, apesar da falha no salvamento. O usuário pode executar comandos para salvar o arquivo em outro lugar ou tentar salvar novamente depois de executar algumas ações fora do programa para corrigir alguma situação.
Solução no TXR: substitua a cópia na memória sem nenhuma estratégia de backup ou recuperação:
#!/usr/local/bin/txr --lisp
(defvarl myname [*args-full* 2])
;; check for required arguments syntax
(unless (and (= (length *args*) 6)
(equal [*args* 0] "-f")
(equal [*args* 2] "--edit"))
(put-line 'usage: @myname -f <file> --edit <col1-key> <col-num> <replace>')
(exit 1))
;; do in-memory update and overwrite
(let ((file [*args* 1])
(key [*args* 3])
(col (pred (tointz [*args* 4]))) ;; pred, because [f #] is zero based
(val [*args* 5])
(ss (make-strlist-output-stream))) ;; in-memory string list stream
;; awk into memory
(awk (:inputs file) ;; input from file
(:output ss) ;; output stream is in-memory string list
(:set fs "|") ;; field separator is pipe
((equal [f 0] key) (set [f col] val)) ;; do replacement
(t)) ;; true condition with no action -> default print action
;; overwrite original file with string list
(with-stream (out (open-file file "w"))
(put-lines (get-list-from-stream ss) out)))
Sessão:
$ diff -u data.orig data
$ ./inplace
usage: ./inplace -f <file> --edit <col1-key> <col-num> <replace>
$ ./inplace -f data --edit 1001 2
usage: ./inplace -f <file> --edit <col1-key> <col-num> <replace>
$ ./inplace -f data --edit 1001 2 Marios
$ diff -u data.orig data
--- data.orig 2016-10-16 08:05:03.233736781 -0700
+++ data 2016-10-16 08:15:57.412394022 -0700
@@ -1,3 +1,3 @@
1000|text1|text2|text3
-1001|text4|text5|text6
+1001 Marios text5 text6
1002|text7|text8|text9