GNU/Linux >> Linux Esercitazione >  >> Linux

Linux:come utilizzare un file come input e output allo stesso tempo?

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:

  1. La shell apre il > file di output per la scrittura, troncandolo
  2. La shell si configura in modo da utilizzare il descrittore di file 1 (per stdout) per quell'output
  3. La shell esegue uniq, forse qualcosa come execlp("uniq", "uniq", ".bash_history", NULL)
  4. 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

Linux
  1. Come acquisire le sessioni del terminale e l'output con il comando di script Linux

  2. Come reindirizzare l'output su un file e Stdout in Linux

  3. Output su Stdout e allo stesso tempo Grep in un file?

  4. Come ottenere l'input e l'output in un terminale in un file di testo?

  5. Come reindirizzare l'output del comando time su un file in Linux?

Comando file Linux:cosa fa e come usarlo

Come usare Sudo e il file Sudoers

Come utilizzare il comando ftp di Linux per caricare e scaricare file sulla shell

File host Linux:come modificarlo e utilizzarlo?

Come creare e utilizzare file di scambio su Linux

Come utilizzare il comando Gzip in Linux?