Comment imprimer les lignes 15 et 25 sur chaque 50 lignes?

9

J'ai un gros fichier et je voudrais imprimer à partir de chaque séquence de 50 lignes, les 15e et 25e lignes.

sed -n '15,25p' inputfile

Comment modifier cette commande pour imprimer uniquement les lignes 15 et 25 et pour boucler sur chaque 50 lignes du fichier.

Mohsen El-Tahawy
la source

Réponses:

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

serait le moyen portable évident.

Notez une sedalternative GNU :

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

Avec tout sed, vous pouvez toujours faire:

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'

(obtenir la ligne suivante 14 fois, imprimer, la ligne suivante 10 fois, imprimer, la ligne suivante 25 fois, revenir au cycle suivant (qui récupère la ligne supplémentaire manquante pour faire 50)).

Stéphane Chazelas
la source
10

c'est un travail pour awk

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

edit: J'ai été induit en erreur par l'instruction sed dans OP.

Archemar
la source
9

Avec perl

1) Similaire à la awksolution, la $.variable stocke le numéro de ligne

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

2) Vérifiez la liste des numéros de ligne, plus facile à étendre

$ 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
la source
4

Une autre approche utilisant awk, basée sur l'idée de Sundeep d'utiliser une liste:

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

Définissez les clés dans le tableau en afonction des lignes que vous souhaitez imprimer. Imprimer les lignes où NR % 50correspond à l'une des clés du tableau.


Pour donner une indication des performances, j'ai chronométré cette approche et comparé aux autres réponses, en prenant une moyenne du usertemps pour 3 runs.

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,542 s

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