GNU/Linux >> Belajar Linux >  >> Linux

Masalah ekspresi reguler di Bash:[^negate] sepertinya tidak berfungsi

Apakah Anda yakin apa yang Anda inginkan terjadi? Ketika Anda menjalankan ls /directory | grep '[^term]' Anda pada dasarnya memahami bukan huruf t e r m. Ini berarti jika file memiliki huruf lain dalam namanya, file tersebut akan tetap muncul di keluaran ls . Ambil contoh direktori berikut:

$ ls
alpha  brave  bravo  charlie  delta

Sekarang jika saya menjalankan ls |grep '^[brav]' Saya mendapatkan yang berikut:

$ ls |grep '^[brav]'
alpha
brave
bravo

Seperti yang Anda lihat, saya tidak hanya mendapatkan brave dan bravo Saya juga mendapatkan alpha karena kelas karakter [] akan mendapatkan surat apa pun dari daftar itu.

Akibatnya, jika saya menjalankan ls |grep '[^brav]' Saya akan mendapatkan semua file yang tidak mengandung karakter b r a v di mana saja dalam nama.

$ ls |grep '[^brav]'
alpha
bravo
brave
charlie
delta

Jika Anda perhatikan itu menyertakan seluruh daftar direktori karena semua file memiliki setidaknya satu huruf yang tidak termasuk dalam kelas karakter.

Jadi seperti yang dikatakan Kanvuanza, untuk memahami kebalikan dari "istilah" sebagai lawan dari karakter t e r m Anda harus melakukannya menggunakan grep -v .

Misalnya:

$ ls |grep -v 'brav'
alpha
charlie
delta

Juga jika Anda tidak ingin file yang memiliki karakter apa pun di kelas gunakan grep -v '[term]' . Itu akan membuat file apa pun tidak muncul yang memiliki karakter tersebut. (Jawaban Kanvuanza)

Misalnya:

$ ls |grep -v '[brav]'

Seperti yang Anda lihat, tidak ada file yang terdaftar karena semua file dalam direktori ini menyertakan setidaknya satu huruf dari kelas tersebut.

Tambahan:

Saya ingin menambahkan bahwa menggunakan PCRE dimungkinkan untuk menggunakan hanya regex untuk memfilter menggunakan ekspresi negasi. Untuk melakukan ini, Anda akan menggunakan sesuatu yang dikenal sebagai regex pandangan ke depan negatif:(?!<regex>) .

Jadi dengan menggunakan contoh di atas, Anda dapat melakukan hal seperti ini untuk mendapatkan hasil yang Anda inginkan tanpa menggunakan grep bendera.

$ ls | grep -P '^(?!brav)'
alpha
charlie
delta

Untuk mendekonstruksi regex itu, regex tersebut pertama kali dicocokkan pada awal baris ^ lalu mencari string yang tidak cocok dengan brav untuk mengikuti sesudahnya. Hanya alpha , charlie , dan delta cocok jadi hanya itu yang dicetak.


Saya kira itu grep -v bendera melakukan apa yang Anda inginkan. Dari halaman manual:

-v, --invert-match
    Invert the sense of matching, to select non-matching lines.

Anda dapat menggunakan ls /directory | grep -v [term] untuk mencetak garis yang tidak cocok.


Linux
  1. Ekspresi reguler:Menarik semuanya bersama-sama

  2. Mengapa Ekspresi Reguler Bekerja Di X Tapi Tidak Di Y?

  3. Bash + Verifikasi Nama Dengan Ekspresi Reguler?

  1. dasar-dasar grep

  2. Cara membalikkan ekspresi grep

  3. Eclipse/Tomcat:penerapan tidak berfungsi lagi (ClassNotFoundException)

  1. LD_LIBRARY_PATH sepertinya tidak berfungsi

  2. Mengapa `\d` tidak berfungsi dalam ekspresi reguler di sed?

  3. Saat menginstal Rust toolchain di Docker, perintah Bash `source` tidak berfungsi