Pencarian case-insensitive dalam awk

20

Saya perlu mencari kata kunci menggunakan awk, tetapi saya ingin melakukan pencarian case-insensitive (non case sensitive).

Saya pikir pendekatan terbaik adalah dengan menggunakan huruf besar istilah pencarian ("kata kunci") dan baris target yang dibaca awk pada saat yang sama. Dari pertanyaan ini saya bagaimana menggunakan toupperuntuk mencetak dalam semua huruf besar, tetapi saya tidak tahu bagaimana menggunakannya dalam pertandingan karena jawaban itu hanya menunjukkan pencetakan dan tidak meninggalkan teks huruf besar dalam variabel.

Berikut ini adalah contoh, diberikan input ini:

blablabla    
&&&Key Word&&&
I want all 
these text and numbers 123
and chars !"£$%&
as output
&&&KEY WORD&&&
blablabla

Saya ingin output ini:

I want all 
these text and numbers 123
and chars !"£$%&
as output

Ini yang saya miliki, tetapi saya tidak tahu cara menambahkan toupper:

awk "BEGIN {p=0}; /&&&key word&&&/ { p = ! p ; next } ; p { print }" text.txt
Woeitg
sumber

Jawaban:

23

Ganti ekspresi Anda untuk mencocokkan pola (yaitu /&&&key word&&&/) dengan ekspresi lain secara eksplisit menggunakan $0, baris saat ini:

tolower($0) ~ /&&&key word&&&/

atau

toupper($0) ~ /&&&KEY WORD&&&/

jadi kamu punya

awk 'tolower($0) ~ /&&&key word&&&/ { p = ! p ; next }; p' text.txt

Anda memerlukan tanda kutip tunggal karena $0 , blok BEGIN dapat dihapus karena variabel diinisialisasi secara default ke ""atau 0pada penggunaan pertama, dan {print}merupakan tindakan default, seperti yang disebutkan dalam komentar di bawah ini.

meuh
sumber
4
Perhatikan bahwa Anda dapat menyederhanakannya menjadi awk 'toupper($0)~/&&&KEY WORD&&&/ { p = ! p ; next } ; p;' text.txt. Tidak perlu untuk BEGINblok dan karena tindakan default adalah untuk mencetak, p;sudah cukup.
terdon
1
"Tidak perlu untuk BEGINblok" karena variabel yang tidak diinisialisasi mengevaluasi sebagai salah.
glenn jackman
Terima kasih atas optimasinya. Saya biasanya mencoba membatasi balasan saya ke perubahan minimal ke aslinya, tetapi memang benar hasilnya baru jauh lebih ketat dan cukup mudah dibaca.
meuh
2
Hanya sebuah catatan: tolowerhadir pada sistem awk versi kuno (atau tidak terlalu kuno) (mis: AIX), tetapi touppertidak selalu tersedia ^^.
Olivier Dulac
16

gawk memiliki IGNORECASEvariabel bawaan, yang, jika disetel ke nol, menyebabkan semua string dan perbandingan ekspresi reguler menjadi case-insensitive. Anda bisa menggunakannya:

BEGIN{IGNORECASE=1}
/&&&key word&&&/ { foo bar baz }

dll. Ini khusus untuk gawk, tetapi saya merasa lebih mudah dibaca daripada alternatif (lebih portabel) oleh meuh. Apakah itu masalah, tentu saja, sepenuhnya terserah Anda.

Wouter Verhelst
sumber
1
Saya ingin mendukung awk selama bertahun-tahun di salah satu proyek gawk terbesar saya, tetapi kurangnya pencarian case-sensitive memicu bahwa gawk menjadikannya non starter karena jumlah case search yang tidak peka terhadap hal-hal yang dijalankan. gensub adalah satu-satunya fitur gawk lain yang terlalu sulit untuk diganti di awk. Tetapi gawk tidak selalu diinstal secara default pada beberapa mesin dan distribusi, meskipun hampir selalu tersedia, tetapi sangat disayangkan bahwa pada tahun 2016 mereka tidak dapat mengubah awk dan posix untuk sedikit memperluas fungsionalitas alat standar semacam itu.
Lizardx
3
@ Lizardx: itulah inti dari tidak berkembang: tetap standar. Kalau tidak, Anda hanya membuat standar lain, dan kemudian Anda memiliki beberapa ketidakmampuan di antara mereka (mereka melakukannya, tetapi mencoba untuk menjaga perubahan standar ke minimum ... bahkan kemudian, beberapa standar adalah salah satu malapetaka komputasi)
Olivier Dulac
2
Saya tidak setuju. Dengan eksekusi yang hati-hati, Anda dapat memperkenalkan ekspansi sambil mendukung semua metode lama, apa yang terjadi jika Anda gagal melakukannya adalah hal-hal yang baru mulai memudar menjadi tidak relevan seiring waktu. Segala sesuatu dalam komputasi berevolusi, triknya adalah mempertahankan evolusi yang andal dan sangat stabil. Bash adalah contoh yang baik untuk melakukan itu, sangat andal dan hanya menambahkan fitur baru, ini bukan 'dua standar' seperti, menggunakan apa yang didukung, dan begitu perubahan telah diluncurkan secara global Anda dapat mulai menggunakan fitur-fitur baru karena hanya sistem warisan tertua tidak akan memiliki dukungan.
Lizardx