2010-01-21 16 views

risposta

249

Se si desidera eliminare le linee da 5 a 10 e 12:

sed -e '5,10d;12d' file 

Questo stamperà i risultati sullo schermo. Se si desidera salvare i risultati allo stesso file:

sed -i.bak -e '5,10d;12d' file 

Ciò eseguire il file fino a file.bak, ed eliminare le linee indicate.

+23

Non tutti gli unix hanno gnu sed con "-i". Non commettere l'errore di ricorrere al "file sed cmd> file", che cancellerà il tuo file. – pra

+2

Cosa fare se volevo cancellare la quinta riga fino all'ultima riga? – Michelle

+8

@WearetheWorld 'sed -e '5, $ d' file' –

14
$ cat foo 
1 
2 
3 
4 
5 
$ sed -e '2d;4d' foo 
1 
3 
5 
$ 
25

e awk così

awk 'NR!~/^(5|10|25)$/' file 
+0

NB: Quella linea di awk ha funzionato in modo più affidabile per me rispetto alla variante sed (tra OS-X e Ubuntu Linux) –

+1

Nota che questo non cancella nulla nel file. Stampa il file senza queste righe sullo stdout. Quindi è necessario reindirizzare l'output in un file temporaneo, quindi spostare il file temporaneo per sostituire l'originale. – mivk

1

Vorrei proporre una generalizzazione con awk.

Quando il file è fatta da blocchi di una dimensione fissa e le linee per eliminare vengono ripetuti per ogni blocco, awk può funzionare bene in modo

awk '{nl=((NR-1)%2000)+1; if ((nl<714) || ((nl>1025)&&(nl<1029))) print $0}' 
OriginFile.dat > MyOutputCuttedFile.dat 

In questo esempio il formato per il il blocco è 2000 e voglio stampare le righe [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)+1 Qui scriviamo nella variabile nl il numero di riga all'interno del blocco corrente. (Vedi sotto)
  • || e && sono l'operatore logico OR e E.
  • print $0 scrive la linea completa

Why ((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  | 
+-----+------+----------+------------+ 

+2

Ammiro il modo in cui vivi fino al tuo nome da follia. –

13

È possibile eliminare una particolare linea singola con il relativo numero di riga per sed -i '33d' file di

Questo cancellerà la riga su 33 numero di riga e salverà il file aggiornato.

3

Questo è molto spesso un sintomo di un antipattern. Lo strumento che ha prodotto i numeri di riga potrebbe essere sostituito con uno che elimina immediatamente le linee.Per esempio;

grep -nh error logfile | cut -d: -f1 | deletelines logfile 

(dove deletelines è l'utilità che si sta immaginando il necessario) è lo stesso di

grep -v error logfile 

Detto questo, se si è in una situazione in cui è realmente necessario eseguire questa attività, è può generare un semplice script sed dal file dei numeri di riga. Umoristicamente (ma forse un po 'confusamente) è possibile farlo con 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 d aggiunti dopo ogni. Si tratta di un sed sceneggiatura valida, che siamo in grado di salvare in un file, o (su alcune piattaforme) Tubo ad un altro sed esempio:

sed 's%$%d%' linenumbers | sed -f - logfile 

Su alcune piattaforme, sed -f non capisce l'argomento opzione - a significare standard input , quindi devi reindirizzare lo script in un file temporaneo e ripulirlo quando hai finito, o magari sostituire il trattino solo con /dev/stdin o /proc/$pid/fd/1 se il tuo sistema operativo (o shell) ha quello.

Come sempre, è possibile aggiungereprima dell'opzione -f per avere sed modificare il file di destinazione in posizione, invece di produrre il risultato sullo standard output. Su piattaforme * BSDish (incluso OSX) è necessario fornire un argomento esplicito a -i; un idioma comune è quello di fornire una discussione vuota; -i ''.

+0

Non sono del tutto d'accordo con "il sintomo di un antipattern". I tipi di file basati su markup (ad esempio XML o JSON) richiedono righe specifiche alla fine per essere file validi. In tal caso, è spesso l'approccio più ragionevole per rimuovere quelle linee, inserire nel file ciò che si desidera aggiungere e quindi aggiungere di nuovo quelle linee, perché mettere le linee in mezzo può essere molto più difficile, e va contro il potenziale desiderio di evitare strumenti extra come sed più che puoi. –

Problemi correlati