Hanya hasil cetak setelah menemukan pola

13

Ada skrip (sebut saja echoer) yang mencetak untuk menyaring banyak informasi. Saya ingin hanya dapat melihat garis setelah pola ditemukan.

Saya membayangkan penggunaan solusi untuk terlihat seperti

echoer | solution_command <pattern>

Idealnya patternakan menjadi ekspresi reguler, tetapi string nilai keras akan cukup bagi saya.

pengguna23146
sumber
Jadi polanya bisa berupa banyak string?
Inian
A glob? Apakah yang Anda maksud adalah ekspresi reguler? Glob hanya masuk akal untuk ekspansi nama file.
terdon
@Inian Saya tidak yakin saya mengerti pertanyaannya. Apakah Anda bermaksud bertanya apakah saya ingin ini berfungsi dengan disjungsi?
user23146

Jawaban:

21

AWK dapat melakukan ini dengan rentang pola, yang memungkinkan penggunaan ekspresi reguler apa pun:

echoer | awk '/pattern/,0'

akan mencetak echoerhasil mulai dengan pencocokan baris pertama pattern.

AWK berbasis pola, dan biasanya digunakan dengan tipe pendekatan "jika pola ini cocok, lakukan ini". "Pola ini" dapat berupa rentang pola, yang didefinisikan sebagai "ketika pola ini cocok, mulailah melakukan ini, hingga pola ini cocok"; ini ditentukan dengan menulis dua pola yang dipisahkan oleh koma, seperti di atas. Pola dapat berupa kecocokan teks, seperti di /pattern/, di mana garis saat ini diperiksa terhadap pola, ditafsirkan sebagai ekspresi reguler; mereka juga bisa menjadi ekspresi umum, dievaluasi untuk setiap baris, dan dianggap cocok jika hasilnya tidak nol atau tidak kosong.

Di AWK, tindakan default adalah mencetak baris saat ini.

Menyatukan semua ini, awk '/pattern/,0'mencari garis yang cocok pattern, dan setelah menemukannya, menerapkan tindakan default untuk semua baris sampai 0kondisinya cocok (tidak nol). awk '/pattern/,""'akan bekerja juga.

The pengguna melongo masuk ke lebih detail.

Stephen Kitt
sumber
3
Saya tidak mengetahui kisaran semantik dengan nol sebagai akhir rentang. Terima kasih!
Kusalananda
@StephenKitt Ini luar biasa! Bagaimana jika saya ingin mencetak sampai cocok 0? Apakah akan /pattern/,/0/? Seperti apa jawabannya bila secara eksplisit menuliskan tindakan default?
user23146
@ user23146 ya, /pattern/,/0/akan mencetak sampai menemukan garis (catatan) yang mengandung "0". Menulis cuplikan dalam jawaban dengan tindakan eksplisit memberi /pattern/,0 { print $0 }, atau setara /pattern/,0 { print }.
Stephen Kitt
7

Wajib sedsetara @ StephenKitt ini awksatu:

sed '/pattern/,$!d'

patternada ditafsirkan sebagai Ekspresi Reguler Dasar seperti dalam grep(sebagai lawan dari Ekspresi Reguler Diperpanjang di awk/ egrep/ grep -E). Beberapa sedimplementasi memiliki opsi -E(BSD, ast, GNU / busybox baru-baru ini, segera POSIX) atau -r(GNU, ssed, busybox, beberapa BSD baru-baru ini) untuk menjadikannya sebagai Extended Regular Expressions, dan beberapa memiliki -P(ast) atau -R(ssed) untuk membuatnya ekspresi reguler seperti perl.

Dengan perl:

perl -ne 'print if /pattern/ .. undef'
Stéphane Chazelas
sumber
4

dengan GNU dan * BSD grep:

grep -A1000000000 pattern file

Kecuali jika file Anda memiliki lebih dari 1 juta baris, itu saja.

mosvy
sumber
0

Jika Anda menggunakan pager seperti lessuntuk melihat output dari perintah

less +pattern
iruvar
sumber
0

awk untuk garis setelah (tetapi tidak termasuk) pencocokan pola pertama

Jika garis yang mengandung pola pemicu setara dengan "CUT HERE", Anda dapat menghilangkannya dari hasil cetak:

echoer | awk 'flag ; /pattern/ { flag=1 }'

Setiap jalur input dijalankan melalui dua komponen dalam kode awk. Komponen pertama adalah flag, yang menafsirkan sebagai "cetak baris jika variabelnya flagbukan nol". Karena variabel awk adalah 0 secara default, ini awalnya tidak akan mencetak apa pun.

Komponen kedua /pattern/ { flag=1 },, mengatur bendera ke 1 segera setelah mendeteksi pola, dan bendera mempertahankan nilai itu selama sisa proses.

Pada saat pola terdeteksi pertama kali, peluang untuk mencetak jalur input telah terlewati. Setiap baris berikutnya (termasuk garis tambahan yang mengandung pola) akan dicetak.

Gaultheria
sumber
0

Pesta

Agak kikuk, tetapi berhasil.

#!/bin/bash
found=false
while IFS= read -r; do
    if $found || [[ $REPLY =~ pattern ]]; then
        found=true
        printf '%s\n' "$REPLY"
    fi
done

Versi ini bergantung cat, tetapi lebih mudah dipahami.

#!/bin/bash
while IFS= read -r; do
    if [[ $REPLY =~ pattern ]]; then
        printf '%s\n' "$REPLY"
        break
    fi
done
cat
wjandrea
sumber