Ekspresi Reguler untuk menemukan karakter ganda di Bash

10

Saya mencari ekspresi reguler yang menemukan semua kemunculan karakter ganda dalam teks, daftar, dll. Di baris perintah (Bash).

Main Pertanyaan : Apakah ada cara sederhana untuk mencari urutan seperti aa, ll, ttttt, dll di mana salah satu mendefinisikan ekspresi reguler yang terlihat untuk n kejadian dari karakter yang sama dengan? Apa yang saya cari adalah mencapai ini pada level yang sangat mendasar. Di baris perintah. Di Linux Shell.

Setelah beberapa penelitian saya datang ke jawaban berikut - dan pertanyaan yang dihasilkan dari mereka, jadi mereka hanya memberi saya petunjuk di mana solusinya. Tapi:

a) (e) grep dan masalah backslash

  • grep 'a\{2\}' mencari aa
  • egrep'a{2}' mencari aa

Pertanyaan: Apakah perlunya mengatur serangan balik benar-benar terikat pada perintah yang saya gunakan? Jika demikian, adakah yang bisa memberi saya petunjuk apa lagi yang harus diperhitungkan saat menggunakan (e) grep di sini?

b) Saya menemukan jawaban ini di sini untuk pertanyaan saya, meskipun itu bukan yang saya cari:

grep -E '(.)\1' filenamemencari entri dengan karakter yang sama muncul lebih dari sekali tetapi tidak menanyakan seberapa sering . Ini dekat dengan apa yang saya cari, tetapi saya masih ingin mengatur sejumlah pengulangan.

Saya mungkin harus membagi ini menjadi dua atau lebih pertanyaan, tetapi kemudian saya tidak ingin membanjiri situs yang luar biasa ini di sini.

PS: Pertanyaan lain, mungkin off topic tapi: apakah in, inside, atatau on the shell. Dan apakah on the command linebenar

erch
sumber

Jawaban:

8

Ini benar-benar dua pertanyaan, dan seharusnya dipisah. Tetapi karena jawabannya relatif sederhana, saya akan meletakkannya di sini. Jawaban-jawaban ini khusus untuk GNU grep.

a) egrepsama dengan grep -E. Keduanya menunjukkan bahwa "Ekspresi Reguler Diperpanjang" harus digunakan daripada grepEkspresi Reguler default. grepmembutuhkan garis miring terbalik untuk Ekspresi Reguler biasa.

Dari manhalaman:

Dasar vs Ekspresi Reguler Diperpanjang

Dalam ekspresi reguler dasar, meta-karakter ? , + , { , | , ( , dan ) kehilangan makna khusus mereka; alih-alih gunakan versi backslashed \? , \ + , \ { , \ | , \ ( , dan \) .

Lihat manhalaman untuk detail tambahan tentang konvensi dan portabilitas historis.

b) Gunakan egrep '(.)\1{N}'dan ganti Ndengan jumlah karakter yang ingin Anda ganti minus satu (karena titik cocok dengan yang pertama). Jadi, jika Anda ingin mencocokkan karakter yang diulang empat kali, gunakan egrep '(.)\1{3}'.

depquid
sumber
Saat membaca halaman manual saya harus benar-benar salah paham atau salah mengartikan bagian yang Anda tunjuk. Ketika saya mengerjakan beberapa tutorial ekspresi reguler, tidak ada petunjuk perilaku seperti yang diharapkan. Saya pikir Ekspresi Reguler berarti sesuatu pada tingkat dasar sehingga sebagian besar aplikasi bekerja dengan set simbol yang sama. Sekali lagi, saya terbukti salah. Terima kasih atas bantuan Anda! Ini sangat membantu saya.
erch
Ini juga bacaan yang cukup membingungkan " selalu menggunakan backslash untuk mengambil makna khusus dari karakter seperti., +, Dll. " Dan kemudian menemukan bahwa yang sebaliknya adalah aturan dengan perintah paling dasar.
erch
@ cellar.dweller Membingungkan! Banyak alasannya historis. Saya lebih terbiasa dengan formulir Extended, jadi saya terbiasa selalu menggunakan egrepjika saya perlu ekspresi reguler (sebagai lawan dari pencocokan string sederhana) sehingga saya tidak perlu khawatir mengingat perbedaan antara grepdua jenis ekspresi reguler.
depquid
4
Perhatikan bahwa ERE standar tidak mendukung referensi balik, sementara BRE standar melakukannya. Begitu grep '\(.\)\1\{3\}'juga standar, grep -E '(.)\1{3}'bukan.
Stéphane Chazelas
7

Ini akan mencari 2 kejadian atau lebih dari karakter yang sama:

grep -E '(.)\1+' file

Jika awk Anda memiliki opsi -o, ini akan mencetak setiap kecocokan pada baris baru ..

grep -Eo '(.)\1+' file

Untuk menemukan kecocokan dengan 3 pencocokan tepat:

grep -E '(.)\1{2}' file

Atau 3 atau lebih:

grep -E '(.)\1{2,}' file

dll ..


sunting

Sebenarnya @stephane_chazelas benar tentang referensi kembali dan -E. Saya sudah lupa tentang itu. Saya mencobanya di BSD grep dan GNU grep dan berfungsi di sana tetapi tidak di beberapa greps lainnya. Anda harus menggunakan salah satu versi di bawah ini ..

Versi grep reguler:

grep '\(.\)\1\{1,\}' file

grep -o '\(.\)\1\{1,\}' file

grep '\(.\)\1\{2\}' file

grep '\(.\)\1\{2,\}' file

The -opilihan juga tidak standar grep BTW (mungkin jika grep Anda mengerti -o juga dapat melakukan referensi kembali) ..


Catatan : grep -E '(.)\1{2,}'file dan grep '\(.\)\1\{2\}'file salah seperti yang ditunjukkan alexis dan harus diabaikan ..

Pengamat
sumber
Terima kasih, sejauh ini Tetapi: Apakah saya benar mengatakan bahwa tanpa -Eopsi greptidak akan banyak membantu? Ini akan menjelaskan banyak hal, misalnya mengapa saya membuang banyak waktu untuk mencari kesalahan saya!
erch
Tanpa opsi -E Anda dapat melakukan hal yang sama dalam hal ini, tetapi Anda harus melarikan diri lebih banyak dan tidak ada +operator .. Saya akan memposting contoh juga.
Scrutinizer
Koreksi kecil: grep -E '(.)\1{2}'tidak persis "Temukan kecocokan dengan 3 kecocokan persis". Sementara itu akan cocok persis tiga karakter identik, mereka dapat tertanam dalam string yang lebih panjang; misalnya, itu akan cocok dengan string 5-simbol AAAAA. (Dan jika ada 6 atau lebih simbol berturut-turut, itu akan cocok lebih dari sekali).
alexis
Ya, Anda memang benar, itu tidak berfungsi sebagaimana dimaksud, pada kenyataannya tidak mungkin seperti itu ..
Scrutinizer
3

Pertama, terima kasih atas komentar dan saran pendukung Anda. Ternyata saya sudah cukup dekat dengan jawabannya.

The Main Issue adalah tentang:

Apakah ada cara sederhana untuk mencari n kejadian dengan karakter yang sama, misalnya aa,tttttt

Jawaban singkat :

Perintah [variasi] berikut ini akan mengulang asetidaknya satu kali dan waktu yang tidak terbatas

grep 'a\{1,}

grep -E \(a\)\{1,\}

egrep a{1,}

atau, dengan GNU Regular Expressions tersedia grep a\+


Jumlah pengulangan diatur di dalam kurung keriting, melalui pola {min,max}{n}ulangi tepat nwaktu, {n,}ulangi setidaknya nkali dan {n,m}ulangi setidaknya ntapi paling banyak mkali.

Dengan demikian, sebagai akibatnya, mengangkat masalah sekunder :

Apakah perlunya menetapkan serangan balik terikat pada perintah yang saya gunakan?

Jawaban singkat : Ya, penggunaan backslash tergantung pada apakah seseorang menggunakan grepatauegrep

  • grep: backslash mengaktifkan metacharacters [menggunakan Basic Regular Expressions]
  • egrepbackslash de -activates metakarakter [kegunaan Diperpanjang Regular Expressions]

Karena ini adalah jawaban singkatnya, saya ingin memberikan kepada mereka yang mengalami masalah yang sebanding, saya menambahkan ringkasan dasar saya tentang apa yang tampaknya harus disadari, bekerja dengan grepdan egrep.




Ekspresi Reguler, Extended, dan GNU

Ekspresi Reguler Dasar

Digunakan dalam grep, eddan sedperintah

Set fitur Ekspresi Reguler Dasar adalah:

  • Sebagian besar Metakarakter, misalnya ? [ . \ )dll. Diaktifkan melalui garis miring terbalik. Jika tidak ada garis miring terbalik mereka akan diambil sebagai (bagian dari) istilah pencarian.
  • ^ $ \<dan \>didukung tanpa backslash
  • Tidak ada karakter singkatan [ \b, \s, dll]

GNU Basic Regular Expressions menambahkannya

  • \?ulangi karakter nol atau satu kali ( c\?cocok cdan cc) dan merupakan alternatif untuk\{0,1\}
  • \+ulangi karakter setidaknya satu kali ( c\+cocok cc, ccccccccdll.) dan merupakan alternatif untuk\{1,\}

  • \|didukung (mis. grep a\|bakan mencari aataub

grep -E memungkinkan perintah untuk menggunakan seluruh rangkaian Ekspresi Reguler Diperpanjang:


Extended Regular Expressions [ERE]

Digunakan dalam egrep, awkdan emacsmerupakan Set Dasar ditambah beberapa fitur.

  • Metakarakter dinonaktifkan melalui garis miring terbalik
  • Tidak ada referensi kembali
  • lain: banyak sihir Regular Expressions biasanya dapat dilakukan untuk satu

GNU Memperpanjang Ekspresi Reguler

menambahkan fitur berikut

Dua tautan akan mengarahkan satu ke regular-expressions.info yang, di samping dukungan awsome yang saya dapatkan di sini, benar-benar banyak membantu saya.

erch
sumber