Soluzione 1:
echo "$(uniq .bash_history)" > .bash_history
dovrebbe avere il risultato desiderato. La subshell viene eseguita prima di .bash_history
è aperto per la scrittura. Come spiegato nella risposta di Phil P, all'ora .bash_history
viene letto nel comando originale, è già stato troncato dal >
operatore.
Soluzione 2:
Consiglio di utilizzare sponge
da moreutils. Dalla manpage:
DESCRIPTION
sponge reads standard input and writes it out to the specified file. Unlike
a shell redirect, sponge soaks up all its input before opening the output file.
This allows for constructing pipelines that read from and write to the same
file.
Per applicare questo al tuo problema, prova:
uniq .bash_history | sponge .bash_history
Soluzione 3:
Il problema è che la tua shell sta configurando la pipeline dei comandi prima di eseguire i comandi. Non è una questione di "input e output", è che il contenuto del file è già andato prima ancora che uniq venga eseguito. Va qualcosa del tipo:
- La shell apre il
>
file di output per la scrittura, troncandolo - La shell si configura in modo da utilizzare il descrittore di file 1 (per stdout) per quell'output
- La shell esegue uniq, forse qualcosa come execlp("uniq", "uniq", ".bash_history", NULL)
- uniq esegue, apre .bash_history e non trova nulla
Esistono varie soluzioni, tra cui la modifica sul posto e l'utilizzo di file temporanei menzionati da altri, ma la chiave è capire il problema, cosa sta effettivamente andando storto e perché.
Soluzione 4:
Un altro trucco per farlo, senza usare sponge
, è il seguente comando:
{ rm .bash_history && uniq > .bash_history; } < .bash_history
Questo è uno dei trucchi descritti nell'eccellente articolo "Modifica sul posto" dei file su backreference.org.
Fondamentalmente apre il file per la lettura, quindi lo "rimuove". Non è realmente rimosso, però:c'è un descrittore di file aperto che punta ad esso, e fintanto che rimane aperto, il file è ancora in giro. Quindi crea un nuovo file con lo stesso nome e vi scrive le righe univoche.
Svantaggio di questa soluzione:Se uniq
fallisce per qualche motivo, la tua cronologia scomparirà.
Soluzione 5:
usa la spugna di moreutils
uniq .bash_history | sponge .bash_history