GNU/Linux >> Belajar Linux >  >> Linux

Tes Shell Apakah Beberapa Baris String Berisi Pola Tertentu Di Baris Terakhir?

Saya ingin menentukan apakah string multi-baris diakhiri dengan garis yang berisi pola tertentu.

Kode ini gagal, tidak cocok.

s=`echo hello && echo world && echo OK`
[[ "$s" =~ 'OK$' ]] && echo match

Jawaban yang Diterima:

Di bash 3.2 atau lebih tinggi dan jika kompatibilitas ke 3.1 tidak diaktifkan (dengan compat31 opsi atau BASH_COMPAT=3.1 ), mengutip operator ekspresi reguler (tidak hanya dengan < tetapi dengan salah satu bash mengutip operator ('...' , "..." , $'...' , $"..." )) menghilangkan arti khusus mereka.

[[ $var =~ 'OK$' ]]

hanya cocok dalam string yang berisi OK$ secara harfiah (itu $ cocok dengan $ . literal )

[[ $var =~ OK$ ]]

cocok pada string yang diakhiri dengan OK (itu $ adalah operator RE yang cocok di akhir string).

Itu juga berlaku untuk regexp yang disimpan dalam variabel atau hasil dari beberapa substitusi.

[[ $var =~ $regexp ]]   # $var matches $regexp
[[ $var =~ "$string" ]] # $var contains $string

Perhatikan bahwa ini bisa menjadi canggung karena ada beberapa karakter yang perlu Anda kutip untuk sintaks shell (seperti kosong, < , > , & , tanda kurung jika tidak cocok). Misalnya, jika Anda ingin mencocokkan dengan .{3} <> [)}]& regexp (3 karakter diikuti oleh " <> " , baik ) atau } dan & ), Anda memerlukan sesuatu seperti:

[[ $var =~ .{3}" <> "[})]& ]]

Jika ragu tentang karakter mana yang perlu dikutip, Anda selalu dapat menggunakan variabel sementara. Itu juga berarti akan membuat kode tersebut kompatibel dengan bash31 , zsh atau ksh93 :

pattern='.{3} <> [})]&'
[[ $var =~ $pattern ]] # remember *not* to quote $pattern here

Itu juga satu-satunya cara (singkat menggunakan compat31 opsi (atau BASH_COMPAT=3.1 )) Anda dapat menggunakan operator tambahan non-POSIX dari regexps sistem Anda.

Misalnya, untuk < untuk diperlakukan sebagai batas kata yang ada di banyak mesin regexp, Anda perlu:

pattern='<word>'
[[ $var =~ $pattern ]]

Melakukan:

[[ $var =~ <word> ]]

tidak akan berfungsi sebagai bash memperlakukan < . itu sebagai operator kutipan shell dan hapus sebelum melewati <word> ke perpustakaan regexp.

Perhatikan bahwa ini jauh lebih buruk di ksh93 di mana:

[[ $var =~ "x.*$" ]]

misalnya akan cocok dengan whatever-xa* tapi bukan whatever-xfoo . Kutipan di atas menghilangkan arti khusus dari * , tetapi tidak untuk . atau $ .

zsh perilaku lebih sederhana:mengutip tidak mengubah arti operator regexp di sana (seperti di bash31) yang membuat perilaku lebih dapat diprediksi (juga dapat menggunakan regexp PCRE alih-alih ERE (dengan set -o rematchpcre )).

Terkait:Opsi menu konteks Nautilus untuk membuat file baru?

yash tidak memiliki [[...]] konstruksi, tetapi [ bawaan memiliki =~ operator (juga dalam zsh ). Dan tentu saja, [ menjadi perintah normal, kutipan tidak dapat memengaruhi cara operator regexp ditafsirkan.

Perhatikan juga bahwa sebenarnya, $s . Anda tidak mengandung 3 baris, tetapi 2 baris penuh diikuti oleh satu baris yang tidak diakhiri. Ini berisi hellonworldnOK . Dalam OK$ ekspresi reguler yang diperluas, $ operator hanya akan cocok di akhir string .

Dalam 3 baris string , seperti hellonworldnOKn (yang tidak akan dapat Anda peroleh dengan substitusi perintah sebagai strip substitusi perintah semua mengikuti karakter baris baru), $ akan cocok setelah n , jadi OK$ tidak cocok dengannya.

Dengan zsh -o pcrematch namun, $ cocok di akhir string dan sebelum baris baru di akhir string jika ada karena tidak lulus PCRE_DOLLAR_ENDONLY tandai ke pcre_compile . Itu bisa dilihat sebagai ide yang buruk karena secara umum, variabel dalam shell tidak mengandung karakter baris baru yang tertinggal, dan ketika mereka melakukannya, kami biasanya ingin mereka dianggap sebagai data.


Linux
  1. Bagaimana cara menulis beberapa baris string menggunakan Bash dengan variabel?

  2. Mengubah banyak baris menjadi satu baris yang dipisahkan koma

  3. Masukkan beberapa baris ke dalam file setelah pola yang ditentukan menggunakan skrip shell

  1. Masukkan beberapa baris data ke file setelah pola cocok menggunakan skrip shell Linux

  2. Bagaimana cara Menghapus baris 'n' Pertama/Terakhir dari output perintah di Shell?

  3. Temukan Nomor Baris Yang Berisi Pola Menggunakan Pembatas Regex Khusus?

  1. Pertahankan Hanya Baris Pertama Dari Setiap Urutan Garis Berturut-turut yang Cocok dengan Pola?

  2. Di shell Linux, bagaimana saya bisa memproses setiap baris dari string multiline?

  3. Cara mengganti string dalam banyak file di baris perintah linux