Come posso estrarre le linee da un file usando il loro numero di linea su UNIX?
-
19-09-2019 - |
Domanda
Utilizzando linee sed o simili come si dovrebbe estrarre da un file? Se volevo linee 1, 5, 1010, 20503 da un file, come avrei potuto ottenere questi 4 righe?
Che cosa succede se ho un gran numero di linee ho bisogno di estrarre? Se avessi un file con 100 linee, ognuna in rappresentanza di un numero di linea che volevo estrarre da un altro file, come posso farlo?
Soluzione
Qualcosa come "sed -n '1p; 5p; 1010p; 20503p'. Eseguire il comando " man sed" per i dettagli
Per la seconda domanda, mi piacerebbe trasformare il file di input in un mazzo di sed (1) i comandi per stampare le linee che volevo.
Altri suggerimenti
con awk è così semplice come:
awk 'NR==1 || NR==5 || NR==1010' "file"
@OP, si può fare questo più facile e più efficiente con awk. Quindi per la vostra prima domanda
awk 'NR~/^(1|2|5|1010)$/{print}' file
per il 2 ° domanda
awk 'FNR==NR{a[$1];next}(FNR in a){print}' file_with_linenr file
Mi piacerebbe indagare Perl, dal momento che ha le strutture regexp del sed
più il modello di programmazione che lo circonda per permettere di leggere un file riga per riga, contare le linee e l'estratto in base a ciò che si desidera (tra cui da un file di numeri di riga).
my $row = 1
while (<STDIN>) {
# capture the line in $_ and check $row against a suitable list.
$row++;
}
Questo non è bello e potrebbe superare i limiti di lunghezza di comando in alcune circostanze * :
sed -n "$(while read a; do echo "${a}p;"; done < line_num_file)" data_file
O il suo molto più lento ma più attraente, e forse più ben educati, fratello:
while read a; do echo "${a}p;"; done < line_num_file | xargs -I{} sed -n \{\} data_file
Una variante:
xargs -a line_num_file -I{} sed -n \{\}p\; data_file
È possibile accelerare le versioni xarg
un po 'aggiungendo l'opzione -P
con alcuni grandi argomenti come, ad esempio, 83 o forse 419 o anche 1177, ma il 10 sembra buono come qualsiasi.
* xargs --show-limits </dev/null
può essere istruttivo
In Perl:
perl -ne 'print if $. =~ m/^(1|5|1010|20503)$/' file