Modifica di file in volo in Linux (scrittura in file di input su un pipe)

Come cambiare un file in volo lungo un pipe?

Probabilmente sto cercando un modo per bufferare un file all'inizio di un pipe, che a differenza di questo:

cat foo.txt | grep bar > foo.txt 

… conserverebbe i dati di input dalla distruzione dal pipe stesso. C'è un tale buffer in magazzino?

  • come mettere i dati in connessione sftp?
  • come mettere un dump di mysql su s3cmd
  • Come faccio a pizzicare l'output di uptime / df per arricciarsi?
  • Redirect output di mysqldump a scp
  • Cattura STDERR e STDOUT al file utilizzando il tee
  • segnali trasparenti su ssh
  • L'output del programma del pipe in un file protetto usando sudo
  • Aggiunta di una barra di avanzamento a un pipe dati
  • 6 Solutions collect form web for “Modifica di file in volo in Linux (scrittura in file di input su un pipe)”

    Vorrei immaginare sed possa ancora creare il file temp, ma i seguenti potrebbero fare quello che vuoi? (Utilizzando strace su questo potrebbe mostrare se sed crea un file temp o no).

     sed -i '/bar/!d' foo.txt 

    L'esclamazione inverte la partita, d è per eliminare, in modo da rimuovere tutte le righe che non hanno bar in loro.

    Provate ad usare spugna da moreutils come questo:

     sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd 

    Raccoglie l'integer input prima di scrivere all'output.

    Usa >> per conservare il contenuto.

    cat foo.txt | grep bar >> foo.txt

    Ora che appenderà al file.

    AFAIK, non esiste alcun metodo diretto per prelevare i dati in un file in shell. Se si desidera eseguire la logging, potrebbe essere necessario utilizzare un file temporaneo in mezzo.

    A seconda della complessità della linea di command, è ansible che il chilometraggio venga eliminato

     cat foo.txt | grep bar | tee -a foo.txt 

    Il modo migliore per farlo è ricordare come funzionano i file in unix – il file esiste finché c'è un collegamento al file (directory o process che apre il file).

    Quindi, apri il file, elimina quella voce di directory, quindi esegue il process che scrive a una nuova voce di directory con lo stesso nome ma collegata ad un altro inodo.

    Infine, la cosa bella di questo è che funziona per qualsiasi tipo di operazione di pipeline, non solo le cose che possono fare il buffer temporaneo di file hack.

     { rm file ; sed -es/this/that/g > file ; } < file 

    Una parola di avvertimento – questo può causare disastri se è necessario che la tua riscrittura sia un'operazione atomica. unix non offre modi puliti per bloccare i file, specialmente non a livello di shell. Questo era un problema nei tempi bui se si stava facendo qualcosa come modificare un file di password in un sistema occupato che eseguiva qualcosa come NIS. Ogni volta che più di un process è la lettura / la scrittura in un file, essere molto attenti se il sistema è occupato o importnte.

    Le uniche operazioni che sono 100% certamente atomiche sono le manipolazioni di immissione di directory – rm / ln / mv (sullo stesso file system).

    Così ora le cose diventano più lunghe e più brutte.

    La parte della math di questo richiede una shell posix o un guscio bourne analogo

     c=0 while f=$SECONDS test -f file.$c.tmp do c=$(($c+1)) done grep stuff < file > file.$c.tmp && mv file.$c.tmp file 

    Ooops, UUOC, uso inutile del gatto 🙂 non c'è bisogno di un gatto lì:

     grep something somefile > someotherfile 

    Come diceva Sekenre, c'è spugna. O forse si potrebbe desiderare di provare perl inline edition (-i switch):

    • printing solo output corrispondente:

      perl -ni -e 'm / foo / g e printingre' bar.txt

    • sostituire "foo" con "bar" nel file:

      perl -pi -e 's / foo / bar / g' bar.txt

    Suggerimenti per Linux e Windows Server, quali Ubuntu, Centos, Apache, Nginx, Debian e argomenti di rete.