Bagaimana cara mencetak baris nomor 15 dan 25 dari setiap 50 baris?

9

Saya memiliki file besar dan saya ingin mencetak dari setiap 50 baris berurutan, baris ke 15 dan 25 .

sed -n '15,25p' inputfile

Cara memodifikasi perintah ini untuk mencetak hanya baris 15 dan 25 dan untuk mengulang setiap 50 baris dalam file.

Mohsen El-Tahawy
sumber

Jawaban:

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

akan menjadi cara portabel yang jelas.

Perhatikan sedalternatif GNU :

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

Dengan apa pun sed, Anda selalu dapat melakukan:

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'

(dapatkan baris berikutnya 14 kali, cetak, baris berikutnya 10 kali, cetak, baris berikutnya 25 kali, kembali ke siklus berikutnya (yang mengambil baris ekstra yang hilang menjadi 50)).

Stéphane Chazelas
sumber
10

ini adalah pekerjaan untuk awk

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

sunting: Saya disesatkan oleh instruksi sed di OP.

Archemar
sumber
9

Dengan perl

1) Mirip dengan awksolusinya, $.variabel menyimpan nomor baris

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

2) Periksa terhadap daftar nomor baris, lebih mudah diperpanjang

$ 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
sumber
4

Pendekatan lain menggunakan awk, berdasarkan ide Sundeep untuk menggunakan daftar:

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

Tetapkan kunci dalam array aberdasarkan pada garis yang ingin Anda cetak. Cetak baris yang NR % 50cocok dengan salah satu kunci dalam array.


Untuk memberikan beberapa indikasi kinerja, saya menghitung waktu pendekatan ini dan membandingkannya dengan jawaban lain, dengan mengambil rata-rata userwaktu selama 3 kali proses.

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,384d

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

0,542-an

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