Voglio eliminare uno o più numeri di riga specifici da un file. Come lo farei usando sed?
Voglio eliminare uno o più numeri di riga specifici da un file. Come lo farei usando sed?
Risposte:
Se si desidera eliminare le righe da 5 a 10 e 12:
sed -e '5,10d;12d' file
Questo stamperà i risultati sullo schermo. Se si desidera salvare i risultati nello stesso file:
sed -i.bak -e '5,10d;12d' file
Questo eseguirà il backup del file file.bake cancellerà le righe indicate.
Nota: i numeri di riga iniziano da 1. La prima riga del file è 1, non 0.
sed -e '5,$d' file
sed -e '5d' file. La sintassi è <address><command>; dove <address>può essere una linea singola 5o un intervallo di linee come 5,10, e il comando delimina la linea o le linee indicate. Gli indirizzi possono anche essere espressioni regolari o il simbolo del dollaro che $indica l'ultima riga del file.
È possibile eliminare una determinata riga singola con il suo numero di riga da
sed -i '33d' file
Ciò eliminerà la riga sul numero di 33 righe e salverà il file aggiornato.
sed -i '0,/<TARGET>/{/<NEW_VALUE>/d;}' '<SOME_FILE_NAME>'. Grazie!
e anche imbarazzato
awk 'NR!~/^(5|10|25)$/' file
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$
Questo è molto spesso un sintomo di un antipasto. Lo strumento che ha prodotto i numeri di riga può essere sostituito con uno che elimina immediatamente le righe. Per esempio;
grep -nh error logfile | cut -d: -f1 | deletelines logfile
(dov'è deletelinesl'utilità che stai immaginando di aver bisogno) è la stessa di
grep -v error logfile
Detto questo, se ti trovi in una situazione in cui hai davvero bisogno di eseguire questa attività, puoi generare un semplice sedscript dal file dei numeri di riga. Con umorismo (ma forse un po 'di confusione) puoi farlo sed.
sed 's%$%d%' linenumbers
Questo accetta un file di numeri di riga, uno per riga, e produce, sullo standard output, gli stessi numeri di riga con l' daggiunta dopo ciascuno. Questo è uno sedscript valido , che possiamo salvare in un file o (su alcune piattaforme) reindirizzare a un'altra sedistanza:
sed 's%$%d%' linenumbers | sed -f - logfile
Su alcune piattaforme, sed -fnon capisce l'argomento opzione -per indicare l'input standard, quindi devi reindirizzare lo script su un file temporaneo e ripulirlo quando hai finito, o forse sostituire il trattino solitario con /dev/stdino /proc/$pid/fd/1se il tuo sistema operativo (o shell ) ha questo.
Come sempre, è possibile aggiungere -iprima -fdell'opzione per sedmodificare il file di destinazione in luogo, invece di produrre il risultato sull'output standard. Su piattaforme * BSDish (incluso OSX) è necessario fornire anche un argomento esplicito -i; un linguaggio comune è quello di fornire un argomento vuoto; -i ''.
pinvece di d, insieme all'opzione -n(non funzionerà senza -ne !dnon funzionerà neanche).
Vorrei proporre una generalizzazione con awk.
Quando il file viene creato da blocchi di dimensioni fisse e le righe da eliminare vengono ripetute per ciascun blocco, awk può funzionare bene in questo modo
awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print $0}'
OriginFile.dat > MyOutputCuttedFile.dat
In questo esempio la dimensione del blocco è 2000 e voglio stampare le linee [1..713] e [1026..1029].
NR è la variabile utilizzata da awk per memorizzare il numero di riga corrente.% fornisce il resto (o modulo) della divisione di due numeri interi;nl=((NR-1)%BLOCKSIZE)+1Qui scriviamo nella variabile nl il numero di riga all'interno del blocco corrente. (vedi sotto)||e &&sono l'operatore logico OR e AND .print $0 scrive la riga completaWhy ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
+1 We add again 1 because we want to restore the desired order.
+-----+------+----------+------------+
| NR | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
| 1 | 1 | 0 | 1 |
| 2 | 2 | 1 | 2 |
| 3 | 0 | 2 | 3 |
| 4 | 1 | 0 | 1 |
+-----+------+----------+------------+