Eseguire operazioni sed su determinati numeri di riga


8

Mi chiedo se esiste un modo semplice per operare su determinate linee con numeri di linea preassegnati.

Diciamo che voglio produrre la prima, la settima, la quattordicesima e la sedicesima riga di un file, posso semplicemente farlo

sed -n '1p;7p;14p;16p' input_file

ma questo diventa più complicato quando l'operazione non sta solo stampando, e non voglio scrivere lo stesso lungo comando 4 volte (e sì, so di poter costruire questo lungo comando sed sostituendo la stessa variabile bash 4 volte, ma non è abbastanza ideale ...), cioè

sed -n '1{long_command};7{long_command};14{long_command};16{long_command}' input_file

C'è un modo per eseguire l'operazione su queste linee specifiche del mio file? Mi aspetto qualcosa di simile,

sed -n '1,7,14,16p'

che certamente non funzionerà nella forma attuale.

Qualsiasi aiuto sarà apprezzato. "No, non è possibile." con le spiegazioni è anche una risposta che accetterò.


è facile conawk
RomanPerekhrest il

Risposte:


11

Puoi usare i rami:

sed '
  1b1
  7b1
  14b1
  16b1

  # for the rest to be left alone, branch off (or delete them with "d"):
  b

  :1
  long_command'

(tieni presente che puoi anche aggiungere alcuni 20,25b1intervalli /re/b1di righe o includere righe corrispondenti a re).

Oppure potresti usare awk:

awk 'NR == 1 || NR == 7 || ... {stuff}'

O usando un hash:

awk -v l=1,7,14,16 '
  BEGIN{split(l, a, ","); for (i in a) lines[a[i]]}

  NR in lines {stuff}'

(o BEGIN{lines[1]lines[7]lines[14]lines[16]}se non ce ne sono troppi)


Grazie, non ho mai pensato ai rami ... Sembra proprio lo strumento ideale da usare in questo caso.
Weijun Zhou,

come si usano i rami come questo in sed con un modello di ricerca? come dire che voglio abbinare o eliminare un modello dopo l'ennesima riga?
qodeninja,

3

Basta invertire la selezione ed eliminarla:

sed '2,6d;8,13d;15d;17,$d;long_command'

Questa è anche una buona soluzione anche se un po 'più difficile per la gestione dei numeri di riga letti da stdin, ad esempio.
Weijun Zhou,

1

Prima variante:

Puoi usare questo trucco:

sed -nf <(printf '%dp\n' 1 7 14 16)

-f file-script - aggiunge il contenuto del file-script ai comandi da eseguire.

analisi

seq 1 20 | sed -nf <(printf '%dp\n' 1 7 14 16)

Produzione

1
7
14
16

Seconda variante:

All'inizio, l'ausiliario sedviene utilizzato per filtrare solo le righe necessarie dal file, quindi queste linee vengono reindirizzate al principale sedcon il comando lungo.

sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.