Sovrascrivi il file solo se i dati


8

Sto cercando di sovrascrivere un file con l'output del comando, ma solo se esiste un output. Cioè, di solito voglio

mycommand > myfile

ma se questo dovesse sovrascrivere myfilecon dati vuoti, desidero conservare la vecchia versione di myfile. Ho pensato che qualcosa usando ifnepotesse essere possibile, a la

mycommand | ifne (cat > myfile) 

ma questo non funziona ...

Un approccio indiretto

mycommand | tee mytempfile | ifne mv mytempfile myfile

funziona, ma considero l'uso di quel file temporaneo non elegante.

D: Perché la mia prima idea non funziona? Può essere fatto funzionare? O c'è un'altra soluzione carina e forse completamente diversa per il mio problema originale?


5
"Il reindirizzamento a un file separato, la verifica della dimensione di quel file e possibilmente la sua ridenominazione" mi sembra piuttosto semplice. Perché non usare un file temporaneo?
Jeff Schaller

Risposte:


18

Il tuo primo approccio funziona, devi solo dare un comando a ifne(vedi man ifne):

NAME
       ifne - Run command if the standard input is not empty

SYNOPSIS
       ifne [-n] command

DESCRIPTION
       ifne  runs  the  following command if and only if the standard input is
       not empty.

Quindi è necessario dargli un comando per l'esecuzione. Ci sei quasi, teefunzionerà:

command | ifne tee myfile > /dev/null

Se il tuo comando non produce un'enorme quantità di dati, se è abbastanza piccolo da adattarsi a una variabile, puoi anche fare:

var=$(mycommand)
[[ -n $var ]] && printf '%s\n' "$var" > myfile

8

La soluzione pedonale:

tmpfile=$(mktemp)

mycommand >"$tmpfile"
if [ -s "$tmpfile" ]; then
    cat "$tmpfile" >myfile
fi

rm -f "$tmpfile"

Cioè, salva l'output in un file temporaneo, quindi verifica se è vuoto o meno. Se non è vuoto, copia il suo contenuto sul tuo file. Alla fine, elimina il file temporaneo.

Sto usando cat "$tmpfile" >myfilepiuttosto che cp "$tmpfile" myfile(o mv) per ottenere lo stesso effetto che avresti ottenuto mycommand >myfile, cioè per troncare il file esistente e preservare la proprietà e le autorizzazioni.

Se $TMPDIR(usato da mktemp) si trova su un filesystem montato in memoria, questo non scriverà su disco se non quando si scrive su myfile. Sarebbe inoltre più portatile dell'uso ifne.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.