A causa di un bug dell'applicazione non ancora diagnosticato, ho diverse centinaia di server con un disco completo. C'è un file che è stato riempito con righe duplicate, non un file di registro, ma un file di ambiente utente con definizioni variabili (quindi non posso semplicemente eliminare il file).
Ho scritto un semplice sed
comando per verificare la presenza di righe erroneamente aggiunte ed eliminarle, e l'ho testato su una copia locale del file. Ha funzionato come previsto.
Tuttavia, quando l'ho provato sul server con l'intero disco, ho ottenuto approssimativamente il seguente errore (è dalla memoria, non dalla copia e incolla):
sed: couldn't flush /path/to/file/sed8923ABC: No space left on deviceServerHostname
Certo, so che non c'è più spazio. Ecco perché sto cercando di eliminare cose! (Il sed
comando che sto usando ridurrà un file di oltre 4000 righe a circa 90 righe.)
Il mio sed
comando è giustosed -i '/myregex/d' /path/to/file/filename
C'è un modo per applicare questo comando nonostante l'intero disco?
(Deve essere automatizzato, poiché devo applicarlo a diverse centinaia di server come soluzione rapida.)
(Ovviamente il bug dell'applicazione deve essere diagnosticato, ma nel frattempo i server non funzionano correttamente ....)
Aggiornamento: la situazione che ho affrontato è stata risolta eliminando qualcos'altro che ho scoperto di poter eliminare, ma mi piacerebbe comunque la risposta a questa domanda, che sarebbe utile in futuro e per le altre persone.
/tmp
è un non-andare; è sullo stesso filesystem.
Prima di liberare spazio su disco, ho eseguito il test e ho scoperto che potevo eliminare le righe vi
aprendo il file ed eseguendolo, :g/myregex/d
quindi salvando correttamente le modifiche con :wq
. Sembra che dovrebbe essere possibile automatizzare questo, senza ricorrere a un filesystem separato per contenere un file temporaneo .... (?)
sed -i
crea una copia temporanea su cui operare. Ho il sospetto che ed
sarebbe meglio per questo, anche se non ho abbastanza familiarità per vietare una soluzione effettiva
ed
te eseguiresti: printf %s\\n g/myregex/d w q | ed -s infile
ma tieni presente che alcune implementazioni usano anche file temporanei proprio come sed
(potresti provare busybox ed - afaik non crea un file temporaneo)
echo
. usare printf
. e sed
aggiungi un po 'di carattere che lasci cadere nell'ultima riga in modo da evitare di perdere spazi vuoti finali. inoltre, la shell deve essere in grado di gestire l'intero file in una singola riga di comando. questo è il tuo rischio: prova prima. bash
è particolarmente brutto (penso che debba fare w / stack space?) e può farti male in qualsiasi momento. i due sed
"si" raccomanderebbero almeno di utilizzare il buffer del kernel del kernel con buoni risultati tra loro, ma il metodo è abbastanza simile. la tua cosa di comando secondaria troncerà anche file
se il sed w / in ha successo.
sed '/regex/!H;$!d;x' <file|{ read v && cat >file;}
e se funziona leggi il resto della mia risposta. '