Bash'de çift karakter bulmak için Normal İfade


10

Komut satırında (Bash) bir metin, bir liste, vb. Çift karakterlerin tüm oluşumlarını bulur normal bir ifade arıyorum.

Ana Soru : gibi dizilerin için bakmak için basit bir yolu var mı aa, ll, tttttvb nerede bir tanımlar, normal bir ifade bununla aynı karakterin n bulunuşu için görünüyor? Aradığım şey, bunu çok temel bir düzeyde başarmak. Komut satırında. Linux Kabuğunda.

Oldukça fazla araştırmadan sonra aşağıdaki cevaplara ve onlardan kaynaklanan sorulara geldim, böylece bana çözümün nerede olabileceğine dair bir ipucu verdiler. Fakat:

a) (e) grep ve ters eğik çizgi sorunu

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

Soru: Boşluk ayarlama zorunluluğu kullandığım komuta gerçekten bağlı mı? Eğer öyleyse, bana burada (e) grep kullanılırken dikkate alınması gereken başka bir şey var mı?

b) Sorum için bu cevabı burada buldum , ancak tam olarak aradığım şey bu değildi:

grep -E '(.)\1' filenameaynı karakterde birden fazla görünen girişleri arar, ancak ne sıklıkta sormaz . Bu aradığım şeye yakın, ama yine de bir dizi tekrar ayarlamak istiyorum.

Muhtemelen bunu iki veya daha fazla soruya bölmeliyim, ama sonra bu harika siteyi buraya taşımak istemiyorum.

Not: Başka bir soru, belki konu dışı ama: o in, inside, atveya on the shell. Ve on the command linedoğru mu?

Yanıtlar:


8

Bu gerçekten iki soru ve bölünmüş olmalıydı. Ama cevaplar nispeten basit olduğu için onları buraya koyacağım. Bu cevaplar grepözellikle GNU içindir .

a) egrepile aynıdır grep -E. Her ikisi de, grepvarsayılan Normal İfadeler yerine "Genişletilmiş Normal İfadeler" kullanılması gerektiğini belirtir . grepdüz Normal İfadeler için ters eğik çizgi gerektirir.

Sayfadan man:

Temel ve Genişletilmiş Düzenli İfadeler

Temel düzenli ifadelerde meta karakterler ? , + , { , | , ( ve ) özel anlamlarını yitirir; bunun yerine ters eğik çizgili sürümleri kullanın \? , \ + , \ { , \ | , \ ( , ve \) .

manTarihsel kurallar ve taşınabilirlik hakkında ek ayrıntılar için sayfaya bakın .

b) Eksi ile değiştirmek istediğiniz karakter sayısını kullanın egrep '(.)\1{N}'ve değiştirin N(nokta birinciyle eşleştiğinden). Bu yüzden dört kez tekrarlanan bir karakteri eşleştirmek istiyorsanız kullanın egrep '(.)\1{3}'.


Man sayfasını okurken işaret ettiğin kısmı gerçekten yanlış anlamış ya da yanlış yorumlamış olmalıyım. Bazı düzenli ifade dersleri üzerinde çalıştığımda beklenen davranışlar hakkında hiçbir ipucu yoktu. Düzenli İfade'nin, çoğu uygulamanın aynı simge kümesiyle çalışacağı kadar temel düzeyde bir şey ifade ettiğini düşündüm. Yine yanlış olduğumu kanıtladım. Yardımın için teşekkürler! Bu gerçekten bana yardımcı oldu.
erch

Ayrıca , " ,., +, Vb. Karakterlerden özel anlamı almak için her zaman ters eğik çizgiyi kullanın " ve daha sonra görünüşte tam tersinin en temel komut olan kural olduğunu bulmak oldukça kafa karıştırıcıdır .
erch

@ cellar.dweller Kafa karıştırıcı! Akıl yürütmenin çoğu tarihseldir. Genişletilmiş forma daha aşinayım, bu yüzden her zaman sadece egrepdüzenli ifadelere ihtiyacım varsa (sadece basit dize eşleşmesinin aksine) kullanmayı alışkanlık haline getiriyorum, böylece grepiki arasındaki farkları hatırlamak konusunda endişelenmem gerekmiyor düzenli ifade türleri.
depquid

4
Standart ERE'lerin geri referansları desteklemediğini, standart BRE'lerin desteklediğini unutmayın. Yani grep '\(.\)\1\{3\}'standart, grep -E '(.)\1{3}'değil.
Stéphane Chazelas

7

Bu, aynı karakterin 2 veya daha fazla oluşumunu arayacaktır:

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

Awk'nuz -o seçeneğine sahipse, bu her eşleşmeyi yeni bir satıra yazdırır.

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

Tam olarak 3 eşleşmeye sahip eşleşmeleri bulmak için:

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

Veya 3 veya daha fazla:

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

vb..


Düzenle

Aslında @stephane_chazelas geri referanslar ve -E konusunda haklı. Bu konuyu unutmuştum. Ben BSD grep ve GNU grep denedim ve orada çalışır ama bazı diğer greps değildir. Aşağıdaki sürümlerden birini kullanmanız gerekir.

Düzenli grep versiyonları:

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

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

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

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

Bu -oseçenek ayrıca standart grep BTW değildir (muhtemelen grep'iniz anlarsa -o da geri referans yapabilir).


Not : alexis belirttiği gibi grep -E '(.)\1{2,}'dosya ve grep '\(.\)\1\{2\}'dosya yanlış ve göz ardı edilmelidir ..


Teşekkürler, şimdiye kadar. Ama: Opsiyon olmadan çok fazla şey yapmayacağını mı-Egrep söyleyebilirim ? Bu oldukça açıklıyor, örneğin yanlış olduğum yeri aramak için neden bu kadar zaman harcadım!
erch

-E seçeneği olmadan bu durumda aynı şeyi yapabilirsiniz, ancak daha fazla kaçmak gerekir ve hiçbir +operatör var .. Ben de örnek göndereceğiz .
Denetmen

Küçük bir düzeltme: grep -E '(.)\1{2}'tam olarak "Tam 3 eşleşmeli eşleşmeleri bul" ifadesini kullanmaz. Tam olarak üç özdeş karakterle eşleşecek olsa da, daha uzun tekrarlanan bir dizeye gömülebilirler; örneğin, 5 sembol dizesiyle eşleşir AAAAA. (Ve arka arkaya 6 veya daha fazla sembol varsa, bir kereden fazla eşleşir).
alexis

Evet kesinlikle haklısın, amaçlandığı gibi çalışmıyor, aslında bu mümkün değil ..
Araştırmacı

3

İlk olarak, destekleyici görüş ve önerileriniz için hepinize teşekkür ederim. Anlaşıldığı üzere, cevaba oldukça yakındım.

Ana Sayı ilgiliydi:

Aynı karakterin n oluşumunu aramanın basit bir yolu var mı , ör aa.tttttt

Kısa cevap :

Aşağıdaki [varyasyonları] komutları aen az bir ve sonsuz kez tekrar eder

grep 'a\{1,}

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

egrep a{1,}

veya GNU Düzenli İfadeleri ile grep a\+


Tekrarlardan sayısı deseni sayesinde, kıvırcık parantez içine ayarlanır {min,max}{n}tekrar tam olarak n, bazen {n,}en azından tekrarını nsüreleri ve {n,m}tekrar en azından nama en fazla mkere.

Böylece, sonuç olarak, ikincil sorunu gündeme getirdi :

Boşluk ayarlama zorunluluğu kullandığım komuta bağlı mı?

Kısa cevap : Evet, ters eğik kullanımı olup olmadığı bir kullanım bağlıdır grepveyaegrep

  • grep: ters eğik çizgi meta karakterleri etkinleştirir [Temel Normal İfadeler kullanır]
  • egrepTers eğik çizgi de -activates meta [kullanımları Normal İfadeleri Genişletilmiş]

Bu Kısa cevap olarak, karşılaştırılabilir sorunları koştu edenlere sağlamak istiyoruz, bir tane dışarı görünüşte ile çalışan, bilinmesi gereken neler benim temel özetini eklendi grepve egrep.




Temel, Genişletilmiş ve GNU Düzenli İfadeleri

Temel Normal İfadeler

Kullanılan grep, edve sedkomuta

Temel Normal İfadeler kümesi özellikleri şunlardır:

  • Çoğu Metakarakter, örneğin, ? [ . \ )vb. Ters eğik çizgi ile etkinleştirilir. Ters eğik çizgi yoksa, arama teriminin bir parçası olarak alınır.
  • ^ $ \<ve \>ters eğik çizgi olmadan desteklenir
  • Hiçbir steno karakterler [ \b, \svb]

GNU Temel Düzenli İfadeler bunlara eklenir

  • \?karakteri sıfır veya bir kez tekrarla ( ve c\?eşleşir ) veccc\{0,1\}
  • \+Bir karakter en az bir kez (tekrar c\+maç cc, ccccccccvs.) ve bir alternatiftir\{1,\}

  • \|desteklenir (örn grep a\|barayacaktır aveyab

grep -E Komutun Genişletilmiş Düzenli İfadelerin tümünü kullanmasını sağlar:


Genişletilmiş Düzenli İfadeler [ERE]

Kullanılan egrep, awkve emacsTemel Set artı oldukça bazı özellikler olduğunu.

  • Meta karakterler bir ters eğik çizgi ile devre dışı bırakılır
  • Geri referans yok
  • başka: sihirli Düzenli İfadelerin çoğu genellikle biri için yapabilir

GNU Uzatmalı Düzenli İfadeler

aşağıdaki özellikleri ekler

İki bağlantı, bir tane düzenli- ifadelere yönlendirecek.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.