Как распечатать строки № 15 и 25 из каждых 50 строк?

9

У меня есть большой файл, и я хотел бы печатать из каждой последовательной 50 строк, 15-й и 25-й строк.

sed -n '15,25p' inputfile

Как изменить эту команду, чтобы печатать только строки 15 и 25 и проходить через каждые 50 строк в файле.

Мохсен Эль-Тахави
источник

Ответы:

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

было бы очевидным портативным способом.

Обратите внимание на sedальтернативу GNU :

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

С любым sed, вы всегда можете сделать:

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'

(получить следующую строку 14 раз, напечатать, следующую строку 10 раз, напечатать, следующую строку 25 раз, вернуться к следующему циклу (который берет недостающую дополнительную строку, чтобы получить 50)).

Стефан Шазелас
источник
10

это работа для awk

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

редактировать: я был введен в заблуждение инструкцией sed в OP.

Archemar
источник
9

С perl

1) Как и в awkрешении, $.переменная хранит номер строки

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

2) Проверить по списку номеров строк, легче расширить

$ 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
источник
4

Другой подход с использованием awk, основанный на идее Sundeep об использовании списка:

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

Установите ключи в массиве aна основе строк, которые вы хотите напечатать. Выведите строки, где NR % 50соответствует один из ключей в массиве.


Чтобы дать некоторое представление о производительности, я рассчитал этот подход и сравнил его с другими ответами, взяв среднее userвремя за 3 прогона.

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
Том Фенек
источник