Il sed
l'approccio va bene, ma il ciclo su tutte le linee non lo è. Se sai quante righe vuoi mantenere (per avere un esempio, qui uso 99), puoi farlo in questo modo:
sed -i '100,$ d' myfile.txt
Spiegazione:sed
è un processore di espressioni regolari. Con l'opzione -i
dato, elabora un file direttamente ("inline"), invece di leggerlo e scrivere i risultati sullo standard output. 100,$
significa semplicemente "dalla riga 100 alla fine del file" -- ed è seguito dal comando d
, che probabilmente hai indovinato correttamente per "eliminare". Quindi, in breve, il comando significa:"Elimina tutte le righe dalla riga 100 fino alla fine del file da miofile.txt". 100 è la prima riga da cancellare, perché vuoi mantenere 99 righe.
Modifica: Se, invece, sono presenti file di log in cui si desidera conservare ad es. l'ultimo 100 righe:
[ $(wc -l myfile.txt) -gt 100 ] && sed -i "1,$(($(wc -l myfile.txt|awk '{print $1}') - 100)) d" myfile.txt
Cosa sta succedendo qui:
[ $(wc -l myfile.txt) -gt 100 ]
:fai quanto segue solo se il file ha più di 100 righe$((100 - $(wc -l myfile.txt|awk '{print $1}')))
:calcola il numero di righe da eliminare (ovvero tutte le righe del file tranne le (ultime) 100 da conservare)1, $((..)) d
:rimuove tutte le righe dalla prima alla riga calcolata
MODIFICA: poiché la domanda è stata appena modificata per fornire maggiori dettagli, includerò anche queste informazioni aggiuntive con la mia risposta. I fatti aggiunti sono:
- una dimensione specifica rimarrà con il file (10.000 byte)
- ogni riga ha una dimensione specifica in byte (300 byte nell'esempio)
Da questi dati è possibile calcolare il numero di righe da rimanere come "/", che con l'esempio significherebbe 33 righe. Il termine shell per il calcolo:$((size_to_remain / linesize))
(almeno su Linux usando Bash, il risultato è un numero intero). Il comando modificato ora sarebbe:
# keep the start of the file (OPs question)
sed -i '34,$ d' myfile.txt
# keep the end of the file (my second example)
[ $(wc -l myfile.txt) -gt 33 ] && sed -i "1,33 d" myfile.txt
Poiché le dimensioni sono note in anticipo, non è più necessario un calcolo incorporato nel sed
comando. Ma per flessibilità, all'interno di alcuni script di shell si possono usare variabili.
Per l'elaborazione condizionale basata sulla dimensione del file, si può usare il seguente costrutto "test":
[ "$(ls -lk $file | awk ' {print $5}')" -gt 100 ] &&
che significa:"se la dimensione di $file
supera i 100kB, fallo..." (ls -lk
elenca la dimensione del file in kB alla posizione 5, quindi awk
viene utilizzato per estrarre esattamente questo).