Como imprimir as linhas 15 e 25 de cada 50 linhas?

9

Eu tenho um arquivo grande e gostaria de imprimir a partir de cada uma das 50 linhas seqüenciais, a 15ª e a 25ª linhas.

sed -n '15,25p' inputfile

Como modificar este comando para imprimir apenas as linhas 15 e 25 e fazer um loop sobre cada 50 linhas no arquivo.

Mohsen El-Tahawy
fonte

Respostas:

22
awk 'NR % 50 == 15 || NR % 50 == 25'

seria a maneira portátil óbvia.

Observe uma sedalternativa GNU :

sed '15~50b;25~50b;d'

Com qualquer sed, você sempre pode:

sed -n 'n;n;n;n;n;n;n;n;n;n;n;n;n;n;p;n;n;n;n;n;n;n;n;n;n;p;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;n'

(pegue a próxima linha 14 vezes, imprima, próxima linha 10 vezes, imprima, próxima linha 25 vezes, volte para o próximo ciclo (que pega a linha extra que falta para fazer 50)).

Stéphane Chazelas
fonte
10

este é um trabalho para awk

awk '(NR%50==15) || (NR%50==25)' inputfile

edit: Eu fui enganado pela instrução sed no OP.

Archemar
fonte
9

Com perl

1) Semelhante à awksolução, a $.variável armazena o número da linha

$ seq 135 | perl -ne 'print if $.%50==15 || $.%50==25'
15
25
65
75
115
125

2) Verifique em relação à lista de números de linha, mais fácil de estender

$ seq 135 | perl -ne 'print if grep {$_==$.%50} (15,25)'
15
25
65
75
115
125

$ seq 135 | perl -ne 'print if grep {$_==$.%50} (15,25,32)'
15
25
32
65
75
82
115
125
132
Sundeep
fonte
4

Outra abordagem usando o awk, com base na idéia do Sundeep de usar uma lista:

awk 'BEGIN { a[15] a[25] }; NR % 50 in a'

Defina as chaves na matriz com abase nas linhas que você deseja imprimir. Imprima linhas onde NR % 50corresponde a uma das chaves na matriz.


Para dar alguma indicação do desempenho, cronometrei essa abordagem e comparei com as outras respostas, tomando uma média do usertempo em três execuções.

0.276s

$ time awk 'BEGIN { a[15] a[25] }; NR % 50 in a' <(seq 1000000) > /dev/null

0.374s

$ time awk 'NR % 50 == 15 || NR % 50 == 25' <(seq 1000000) > /dev/null

0.384s

$ time perl -ne 'print if $.%50==15 || $.%50==25' <(seq 1000000) > /dev/null

0.542s

$ time perl -ne 'print if grep {$_==$.%50} (15,25)' <(seq 1000000) > /dev/null
Tom Fenech
fonte