Menü
Bedava
giriş
ev  /  Programlar / Unix normal ifadeleri. Linux'ta normal ifadeler (regex) kullanma

Unix normal ifadeleri. Linux'ta normal ifadeler (regex) kullanma

Orijinal: Linux Temelleri
Yazar: Paul Cobbaut
Yayın Tarihi: 16 Ekim 2014
Tercüme: A. Panin
Transfer tarihi: 17 Aralık 2014

Bölüm 19. Normal İfadeler

Normal ifade motoru, Linux sisteminde çok güçlü bir araçtır. Düzenli ifadeler bash, vi, rename, grep, sed ve diğerleri gibi birçok programla kullanılabilir.

Bu bölüm, normal ifadeler hakkında temel bilgiler sağlar.

Normal İfade Söz Dizimi Sürümleri

Normal ifade sözdizimlerinin üç farklı sürümü vardır: BRE: Temel Normal İfadeler ERE: Genişletilmiş Normal İfadeler PCRE: Perl Normal İfadeler

Kullanılan araca bağlı olarak bahsedilen sözdizimlerinin biri veya daha fazlası kullanılabilir.

Örneğin, grep aracı normal bir ifadeyi ayrıştırırken genişletilmiş normal ifade sözdizimi (ERE) kullanımını zorlamak için -E seçeneğini desteklerken, -G seçeneği temel normal ifade sözdizimini (BRE) kullanılmaya zorlar ve -P seçeneği Perl programlama dili düzenli ifade sözdizimi (PCRE).

Grep'in ayrıca normal ifadeyi işlemeden okumak için -F seçeneğini de desteklediğini unutmayın.

Sed aracı ayrıca normal ifadelerin sözdizimini seçmenize izin veren seçenekleri de destekler.

Daima kullandığınız aletlerin kılavuz sayfalarını okuyun!

Grep yardımcı programı

Bir desenle eşleşen dizelerin çıktısını alma

Grep yardımcı programı, belirli bir kalıpla eşleşen dizeleri bulmak için popüler bir Linux sistem aracıdır. Aşağıda, onunla çalışırken kullanılabilecek en basit normal ifadelere örnekler verilmiştir.

Bu, örneklerde kullanılan test dosyasının içeriğidir. Bu dosya üç satır (veya üç satır) içerir. [e-posta korumalı]: ~ $ kedi isimleri Tania Laura Valentina

Tek bir karakter aranırken, sadece belirtilen karakteri içeren dizeler görüntülenecektir. [e-posta korumalı]: ~ $ grep u isimleri Laura [e-posta korumalı]: ~ $ grep e ismi Valentina [e-posta korumalı]: ~ $ grep, Tania Valentina adını veriyorum

Bu örnekte kullanılan model ile karşılaştırma basittir; belirli bir karakterin bir dizede yer alması durumunda, grep bu dizeyi basacaktır.

Karakterleri birleştirmek

Dizelerdeki karakter kombinasyonlarını aramak için normal ifade karakterleri aynı şekilde birleştirilmelidir.

Bu örnek, grep yardımcı programının nasıl çalıştığını gösterir; buna göre normal ifade ia, Tan ia dizesiyle eşleşir, ancak V a ödünç verilmiş dizesiyle eşleşmez ve normal ifade a içindeki Valent dizesiyle eşleşir, ancak Ta ni a dizesiyle eşleşmez. [e-posta korumalı]: ~ $ grep a isimleri Tania Laura Valentina [e-posta korumalı]: ~ $ grep ia isimleri Tania [e-posta korumalı]: ~ $ grep adıyla Valentina [e-posta korumalı]:~$

Bir veya diğer sembol

Hem PCRE sözdizimi hem de ERE sözdizimi, bu durumda mantıksal bir OR işlemini temsil edecek olan boru oluşturma sembolünü kullanabilir. Bu örnekte, bir i veya karakter içeren satırları aramak için grep yardımcı programını kullanacağız. [e-posta korumalı]: ~ $ kedi listesi Tania Laura [e-posta korumalı]: ~ $ grep -E "i | a" listesi Tania Laura

Normal ifademizin Genişletilmiş Normal İfade Sözdizimi (ERE) kullanılarak bir ifade olarak yorumlanmasını zorlamak için grep için -E seçeneğini kullandığımıza dikkat edin.

Boruyu mantıksal VEYA aynı şekilde yorumlamak için Temel Normal İfade (BRE) sözdizimini kullanarak normal ifadede boru oluşturma karakterinden kaçmamız gerekecek. [e-posta korumalı]: ~ $ grep -G "i | a" listesi [e-posta korumalı]: ~ $ grep -G "i \\ | a" listesi Tania Laura

Bir veya daha fazla eşleşme

* Karakteri, önceki karakterin sıfır, bir veya daha fazla oluşumuyla eşleşir ve + karakteri aşağıdaki karakterle eşleşir. [e-posta korumalı]: ~ $ kedi listesi2 ll lol lool loool [e-posta korumalı]: ~ $ grep -E "o *" liste2 ll lol lool loool [e-posta korumalı]: ~ $ grep -E "o +" list2 lol lool loool [e-posta korumalı]:~$

Satır sonu eşleşmesi

Aşağıdaki örneklerde bu dosyayı kullanacağız: [e-posta korumalı]: ~ $ kedi isimleri Tania Laura Valentina Fleur Floor

Aşağıdaki iki örnek, bir dizenin sonunda bir eşleşme bulmak için dolar işaretini kullanmaya yönelik bir tekniği göstermektedir. [e-posta korumalı]: ~ $ grep a $ names Tania Laura Valentina [e-posta korumalı]: ~ $ grep r $ isimleri Fleur Floor

Satırın başında eşleştirme

Düzeltme işareti (^), bir dizenin başında (veya ilk karakterlerinde) bir eşleşme aramanızı sağlar.

Bu örnekler, yukarıda tartışılan dosyayı kullanır. [e-posta korumalı]: ~ $ grep ^ Val ismi Valentina [e-posta korumalı]: ~ $ grep ^ F isimleri Fleur Floor

Normal ifadelerde kullanılan dolar karakterleri ve eklemelere çapa denir.

Kelimeleri bölme

Arama sözcüklerinden boşluklarla kaçmak iyi bir çözüm değildir (çünkü diğer karakterler de sözcük ayırıcı olarak kullanılabilir). Aşağıdaki örnek, bir karakter dizisi yerine belirli bir kelimeye sahip dizeleri aramak için \\ b karakter dizisini kullanmaya yönelik bir tekniği göstermektedir: [e-posta korumalı]: ~ $ grep "\\ bover \\ b" text Kış bitti. Oraya gidebilir misin? [e-posta korumalı]:~$

Grep'in kelime aramaları için -w seçeneğini de desteklediğini unutmayın. [e-posta korumalı]: ~ $ kedi metni Yönetici yönetiyor. Kış bitti. Oraya gidebilir misin? [e-posta korumalı]: ~ $ grep -w metin üzerinde Kış bitti. Oraya gidebilir misin? [e-posta korumalı]:~$

Grep seçenekleri

Bazen basit bir normal ifadeyi grep seçenekleriyle birleştirmek, daha karmaşık bir normal ifade oluşturmaktan daha kolaydır. Bu seçenekler daha önce tartışılmıştı: grep -i grep -v grep -w grep -A5 grep -B5 grep -C5

Kabuğun normal ifadeyi genişletmesini önleme

Dolar işareti, hem normal ifadeler hem de kabuklar için özel bir karakterdir (kabuk değişkenlerini ve gömülü kabukları düşünün). Bu nedenle, normal ifadelerden her koşulda kaçınmanız önerilir, çünkü bir normal ifadeden kaçmak kabuğun bu ifadeyi genişletmesini engeller. [e-posta korumalı]: ~ $ grep "r $" adları Fleur Floor yeniden adlandır

Yardımcı programı yeniden adlandır

Yardımcı program uygulamalarını yeniden adlandırın

Debain Linux dağıtımında, / usr / bin / rename yolu perl paketinden yüklenen / usr / bin / prename betiğine bir bağlantı içerir. [e-posta korumalı] ~ $ dpkg -S $ (readlink -f $ (yeniden adlandırılır)) perl: / usr / bin / prename

Red Hat tabanlı dağıtımlar, açıklanan betiğe işaret etmek için benzer bir sembolik bağlantı oluşturmaz (elbette, manuel olarak yüklenen bir betiğe sembolik bir bağlantı oluşturma haricinde), bu nedenle bu bölüm yeniden adlandırma yardımcı programının uygulamasını açıklamayacaktır. Red Hat dağıtımı.

İnternetteki yeniden adlandırma uygulamasıyla ilgili tartışmalarda genellikle Debian dağıtımında mükemmel çalışan çözümlerin (Ubuntu, xubuntu, Mint, ...) Red Hat dağıtımında (ve ayrıca CentOS) kullanılamaması nedeniyle kafa karışıklığı oluşur. , Fedora, ...).

Perl paketi

Yeniden adlandırma komutu aslında perl programlama dilinin normal ifadelerini kullanan bir komut dosyası olarak uygulanır. Bu komut dosyasını kullanmanın tam bir kılavuzu, perldoc perlrequick komutunu girdikten sonra (perldoc paketini kurduktan sonra) bulunabilir. [e-posta korumalı]: ~ # aptitude install perl-doc Aşağıdaki YENİ paketler yüklenecek: perl-doc 0 paket güncellendi, 1 yeni paket yüklendi, 0 paket kaldırılmak üzere işaretlendi ve 0 paket güncellenmedi. 8.170 kB arşiv almanız gerekiyor. Ambalajı açtıktan sonra 13,2 MB kullanılacaktır. Alın: 1 http://mirrordirector.raspbian.org/raspbian/ wheezy / main perl-do ... 19 saniyede 8.170 kB alındı \u200b\u200b(412 kB / s) Daha önce seçilmemiş bir perl-doc paketi seçin. (Veritabanı okunuyor ... açık şu an 67121 dosya ve dizin kurulu.) Perl-doc paketinden çıkarılıyor (... / perl-doc_5.14.2-21 + rpi2_all.deb'den) ... / usr / bin / perldoc'un / usr / bin / perldoc'a yönlendirilmesi "ekleniyor. stub by perl-doc "man-db için tetikleyiciler işleniyor ... perl-doc paketi yapılandırılıyor (5.14.2-21 + rpi2) ... [e-posta korumalı]: ~ # perldoc perlrequick

İyi bilinen sözdizimi

Yeniden adlandırma yardımcı programının en yaygın kullanımı, bir dize biçiminde belirli bir desenle eşleşen adlara sahip dosyaları bulmak ve bu dizeyi başka bir dizeyle değiştirmektir.

Genellikle bu işlem, örnekte gösterildiği gibi, s / string / başka bir dize / normal ifadesi kullanılarak açıklanır: [e-posta korumalı] ~ $ ls abc allfiles.TXT bllfiles.TXT Scratch Tennis2.TXT abc.conf yedekleme cllfiles.TXT temp.TXT Tennis.TXT [e-posta korumalı] ~ $ "s / TXT / metin /" yeniden adlandır * [e-posta korumalı] ~ $ ls abc allfiles.text bllfiles.text Scratch Tennis2.text abc.conf yedekleme cllfiles.text temp.text tenis.text

Aşağıda, aynı dosyaların uzantılarını yeniden değiştirmek için yeniden adlandırma yardımcı programının iyi bilinen sözdizimini kullanan başka bir örnek verilmiştir: [e-posta korumalı] ~ $ ls abc allfiles.text bllfiles.text Scratch Tennis2.text abc.conf yedekleme cllfiles.text temp.text tenis.text [e-posta korumalı] ~ $ yeniden adlandır "s / text / txt /" * .text [e-posta korumalı] ~ $ ls abc allfiles.txt bllfiles.txt Scratch Tennis2.txt abc.conf yedekleme cllfiles.txt temp.txt Tennis.txt [e-posta korumalı] ~ $

Bu iki örnek uygulanabilir çünkü kullandığımız dizeler sadece dosya uzantılarında görünüyor. Bash kabuğunu kullanırken dosya uzantılarının alakasız olduğunu unutmayın.

Aşağıdaki örnek, bu sözdizimini kullanırken karşılaşabileceğiniz bir sorunu göstermektedir. [e-posta korumalı] ~ $ touch atxt.txt [e-posta korumalı] ~ $ "s / txt / problem /" atxt.txt dosyasını yeniden adlandır [e-posta korumalı] ~ $ ls abc allfiles.txt yedekleme cllfiles.txt temp.txt Tennis.txt abc.conf aproblem.txt bllfiles.txt Scratch Tennis2.txt [e-posta korumalı] ~ $

Söz konusu komutu çalıştırırken, sadece aranan dizenin ilk geçtiği yer değiştirilir.

Küresel değiştirme

Önceki örnekte kullanılan sözdizimi şu şekilde açıklanabilir: s / regex / replace string /. Bu açıklama basit ve anlaşılırdır, çünkü yalnızca ilk iki eğik çizgi arasına bir normal ifade ve son iki eğik çizgi arasına bir yedek dize yerleştirmeniz gerekir.

Aşağıdaki örnek, bir değiştirici ekleyerek bu sözdizimini biraz genişletir. [e-posta korumalı] ~ $ yeniden adlandır -n "s / TXT / txt / g" aTXT.TXT aTXT.TXT, atxt.txt olarak yeniden adlandırıldı [e-posta korumalı] ~ $

Şimdi kullandığımız sözdizimi, s / normal ifade / değiştirme dizesi / g olarak tanımlanabilir; burada s değiştiricisi bir anahtar işlemini belirtir ve g değiştiricisi uygulama ihtiyacını belirtir küresel ikame (küresel).

Bu örnekte, -n parametresinin, gerçekleştirilen işlemle ilgili bilgileri görüntülemek için kullanıldığına dikkat edin (dosyayı doğrudan yeniden adlandırmak olan işlemin kendisini gerçekleştirmek yerine).

Büyük / küçük harfe duyarlı olmayan değiştirme

Yararlı bulabileceğiniz başka bir değiştirici, i değiştiricidir. Aşağıdaki örnek, büyük / küçük harfe duyarlı olmayan bir şekilde bir dizeyi başka bir dizeyle değiştirmek için bir tekniği göstermektedir. [e-posta korumalı]: ~ / dosyalar $ ls dosya1.text dosya2.TEXT dosyası3.txt [e-posta korumalı]: ~ / dosyalar $ yeniden adlandır "s / .text / .txt / i" * [e-posta korumalı]: ~ / dosyalar $ ls dosya1.txt dosya2.txt dosya3.txt [e-posta korumalı]: ~ / dosyalar $

Uzantıları değiştirme

Komut arayüzü linux dizeleri MS-DOS işletim sisteminde kullanılanlara benzer dosya uzantıları hakkında hiçbir fikri yoktur, ancak birçok kullanıcı ve GUI uygulaması bunları kullanır.

Bu bölümde, yalnızca dosya uzantılarını değiştirmek için yeniden adlandırma yardımcı programını kullanma örneği verilmektedir. Örnek, dosya adının sonunun değiştirme için başlangıç \u200b\u200bnoktası olduğunu belirtmek için bir dolar işareti kullanır. [e-posta korumalı] ~ $ ls * .txt allfiles.txt bllfiles.txt cllfiles.txt really.txt.txt temp.txt Tennis.txt [e-posta korumalı] ~ $ yeniden adlandır "s / .txt $ /. TXT /" * .txt [e-posta korumalı] ~ $ ls * .TXT allfiles.TXT bllfiles.TXT cllfiles.TXT really.txt.TXT temp.TXT Tennis.TXT [e-posta korumalı] ~ $

Normal ifadedeki dolar işaretinin bir satırın sonunu gösterdiğini unutmayın. Dolar işareti olmadan, gerçekten.txt.txt dosya adı işlendiğinde bu komutun yürütülmesi başarısız olmalıdır.

Sed yardımcı programı

Veri akışı düzenleyicisi

Akış düzenleyicisi veya kısaca sed, veri akışını değiştirmek için normal ifadeler kullanır.

Bu örnekte sed, bir dizeyi değiştirmek için kullanılır. echo Pazartesi | sed "s / Pazartesi / Salı /" Salı

Eğik çizgiler, daha uygun olabilecek ve bazı durumlarda komutun okunabilirliğini artırabilecek başka bazı karakterlerle değiştirilebilir. echo Pazartesi | sed "s: Pazartesi: Salı:" Salı echo Pazartesi | sed "s_Week_Tue_" Salı echo Pazartesi | sed "s | Pazartesi | Salı |" Salı

Etkileşimli düzenleyici

Sed, veri akışlarını işlemek için tasarlanmış olsa da, dosyaları etkileşimli olarak işlemek için de kullanılabilir. [e-posta korumalı]: ~ / files $ echo Pazartesi\u003e bugün [e-posta korumalı]: ~ / files $ cat bugün Pazartesi [e-posta korumalı]: ~ / files $ sed -i "s / Pazartesi / Salı /" bugün [e-posta korumalı]: ~ / files $ cat bugün Salı

Ve işareti karakteri, arama (ve bulunan) dizesine başvurmak için kullanılabilir.

Bu örnekte, bulunan satır sayısını ikiye katlamak için ve işareti kullanılır. echo Pazartesi | sed "s / Pazartesi / && /" PazartesiPazartesi echo Pazartesi | sed "s / nick / && /" Pazartesi

Parantezler, normal ifadenin daha sonra başvurulabilecek bölümlerini gruplamak için kullanılır.

Aşağıdaki örneği düşünün: [e-posta korumalı]: ~ $ echo Pazar | sed "s _ \\ (Güneş \\) _ \\ 1ny_" Sunnyday [e-posta korumalı]: ~ $ echo Pazar | sed "s _ \\ (Sun \\) _ \\ 1ny \\ 1_" Güneşli Pazar

Herhangi bir karakteri belirtmek için nokta

Normal bir ifadede, basit bir nokta karakteri herhangi bir karakteri temsil edebilir. [e-posta korumalı]: ~ $ echo 2014-04-01 | sed "s /....-..-../ YYYY-AA-GG /" YYYY-AA-GG [e-posta korumalı]: ~ $ echo abcd-ef-gh | sed "s /....-..-../ YYYY-AA-GG /" YYYY-AA-GG

Birden fazla parantez çiftinin kullanılması durumunda, her biri ardışık sayısal değerler kullanılarak referans alınabilir. [e-posta korumalı]: ~ $ echo 2014-04-01 | sed "s / \\ (.... \\) - \\ (.. \\) - \\ (.. \\) / \\ 1+ \\ 2+ \\ 3 /" 2014 + 04 + 01 [e-posta korumalı]: ~ $ echo 2014-04-01 | sed "s / \\ (.... \\) - \\ (.. \\) - \\ (.. \\) / \\ 3: \\ 2: \\ 1 /" 01: 04: 2014

Bu özelliğe gruplama denir.

Uzay

\\ In karakter dizisi boşluk veya sekme karakteri gibi bir karaktere başvurmak için kullanılabilir.

Bu örnek, genel olarak 1 boşluk karakteri ile değiştirilen boşluk (\\ s) karakter dizilerini arar. [e-posta korumalı]: ~ $ echo -e "bugün \\ t \\ t \\ t gün" bugün sıcak bir gün [e-posta korumalı]: ~ $ echo -e "Bugün ılık" | sed "s_ \\ s_ _g" bugün sıcak bir gün

İsteğe bağlı olaylar

Soru işareti simgesi, önceki karakterin isteğe bağlı olduğunu belirtir.

Aşağıdaki örnek, üç o'nun isteğe bağlı olduğu bir dizi arar. [e-posta korumalı]: ~ $ kedi listesi2 ll lol lool loool [e-posta korumalı]: ~ $ grep -E "ooo?" list2 lool loool [e-posta korumalı]: ~ $ kedi listesi2 | sed "s / ooo \\? / A /" ll lol lAl lAl

Tam olarak n tekrar

Önceki karakterin tam tekrar sayısını belirtebilirsiniz.

Bu örnek, tam olarak üç o karakterli dizeleri arar. [e-posta korumalı]: ~ $ kedi listesi2 ll lol lool loool [e-posta korumalı]: ~ $ grep -E "o (3)" list2 loool [e-posta korumalı]: ~ $ kedi listesi2 | sed "s / o \\ (3 \\) / A /" ll lol lool lAl [e-posta korumalı]:~$

N'den m'ye tekrarlar

Ve bu örnekte, sembolün minimumdan (2) maksimuma (3) kadar tekrarlanması gerektiğini açıkça belirtiyoruz. [e-posta korumalı]: ~ $ kedi listesi2 ll lol lool loool [e-posta korumalı]: ~ $ grep -E "o (2,3)" list2 lool loool [e-posta korumalı]: ~ $ grep "o \\ (2,3 \\)" list2 lool loool [e-posta korumalı]: ~ $ kedi listesi2 | sed "s / o \\ (2,3 \\) / A /" ll lol lAl lAl [e-posta korumalı]:~$

Bash kabuğu geçmişi

Bash kabuğu, bazı düzenli ifadeleri de yorumlayabilir.

Bu örnek, bash kabuğu geçmişindeki arama maskesi içindeki ünlem işareti karakterini işlemek için bir tekniği gösterir. [e-posta korumalı]: ~ $ mkdir geçmiş [e-posta korumalı]: ~ $ cd geçmişi / [e-posta korumalı]: ~ / hist $ touch dosya1 dosya2 dosya3 [e-posta korumalı]: ~ / hist $ ls -l dosya1 -rw-r - r-- 1 paul paul Nis 0 15 22:07 dosya1 [e-posta korumalı]: ~ / hist $! l ls -l dosya1 -rw-r - r-- 1 paul paul 0 Nis 15 22:07 dosya1 [e-posta korumalı]: ~ / hist $! l: s / 1/3 ls -l dosya3 -rw-r - r-- 1 paul paul 0 Nis 15 22:07 dosya3 [e-posta korumalı]: ~ / hist $

Bu teknik, bash kabuğunun komut geçmişini okurken sayıları kullanırken de işe yarar. [e-posta korumalı]: ~ / hist $ geçmiş 6 2089 mkdir hist 2090 cd hist / 2091 touch dosya1 dosya2 dosya3 2092 ls -l dosya1 2093 ls -l dosya3 2094 geçmişi 6 [e-posta korumalı]: ~ / hist $! 2092 ls -l dosya1 -rw-r - r-- 1 paul paul 0 Nis 15 22:07 dosya1 [e-posta korumalı]: ~ / hist $! 2092: s / 1/2 ls -l dosya2 -rw-r - r-- 1 paul paul 0 Nis 15 22:07 dosya2 [e-posta korumalı]: ~ / hist $

Sed ve awk kullanarak bash betiklerinde metinleri tam olarak işlemek için, sadece normal ifadeleri anlamanız gerekir. Bu çok kullanışlı aracın uygulamaları kelimenin tam anlamıyla her yerde bulunabilir ve tüm düzenli ifadeler benzer şekilde, aynı fikirlere dayalı olarak düzenlenmiş olsa da, onlarla çalışmanın farklı ortamlarda belirli özellikleri vardır. Burada betiklerde kullanılmaya uygun normal ifadelerden bahsedeceğiz. komut satırı Linux.

Bu materyalin, ne olduğunu hiç bilmeyenler için normal ifadelere bir giriş olması amaçlanmıştır. Öyleyse en baştan başlayalım.

Normal ifadeler nelerdir

Birçoğu için, normal ifadeleri ilk gördüklerinde, hemen anlamsız bir karakter karmaşasının önünde olduklarını düşünürler. Ancak bu elbette durumdan uzaktır. Örneğin bu normal ifadeye bir göz atın


Bize göre, mutlak bir acemi bile nasıl çalıştığını ve neden ihtiyaç duyduğunuzu hemen anlayacaktır :) Tam olarak anlamıyorsanız, okumaya devam edin ve her şey yerine oturacaktır.
Normal ifade, sed veya awk gibi programları metni filtrelemek için kullanan bir kalıptır. Şablonlar, kendilerini temsil etmek için normal ASCII karakterlerini ve örneğin belirli karakter gruplarına atıfta bulunmanıza izin veren özel bir rol oynayan meta karakterleri kullanır.

Normal ifade türleri

Java, Perl ve Python gibi programlama dilleri ve sed, awk ve grep gibi Linux araçları gibi çeşitli ortamlarda düzenli ifade uygulamalarının bazı tuhaflıkları vardır. Bu özellikler, kalıpları yorumlayan sözde normal ifade motorlarına bağlıdır.
Linux iki normal ifade motoruna sahiptir:
  • POSIX Basic Regular Expression (BRE) standardını destekleyen bir motor.
  • POSIX Extended Regular Expression (ERE) standardını destekleyen bir motor.
Çoğu Linux yardımcı programı, en azından POSIX BRE standardına uygundur, ancak bazı yardımcı programlar (sed dahil) BRE standardının yalnızca bir alt kümesini anlar. Bu sınırlamanın nedenlerinden biri, bu tür yardımcı programları kelime işlemde olabildiğince hızlı yapma arzusudur.

POSIX ERE standardı genellikle programlama dillerinde uygulanır. Normal ifadeler tasarlarken birçok araç kullanmanıza izin verir. Örneğin, metinde arama yapmak gibi sık kullanılan kalıplar için özel karakter dizileri olabilir. tekil kelimeler veya sayı kümeleri. Awk, ERE standardını destekler.

Programcının görüşüne ve yaratıldıkları motorun özelliklerine bağlı olarak düzenli ifadeler geliştirmenin birçok yolu vardır. Herhangi bir motorun anlayabileceği genel düzenli ifadeler yazmak kolay değildir. Bu nedenle, en sık kullanılan düzenli ifadelere odaklanacağız ve sed ve awk için nasıl uygulandıklarına bir göz atacağız.

POSIX BRE Normal İfadeler

Belki de en basit BRE kalıbı, metindeki bir karakter dizisinin tam olarak geçtiği yeri bulmak için düzenli bir ifadedir. Bir dizge için sed ve awk şöyle görünür:

$ echo "Bu bir testtir" | sed -n "/ test / p" $ echo "Bu bir denemedir" | awk "/ test / (yazdır $ 0)"

Sed'de kalıba göre metin arama


Awk'de kalıba göre metin bulma

Dizideki metnin tam konumu hesaba katılmadan belirli bir model için aramanın yapıldığını fark edebilirsiniz. Ek olarak, olayların sayısı önemli değil. Normal ifade, verilen metni dizenin herhangi bir yerinde bulduktan sonra, dize geçerli kabul edilir ve daha fazla işlem için aktarılır.

Normal ifadelerle çalışırken, büyük / küçük harfe duyarlı olduklarını unutmayın:

$ echo "Bu bir testtir" | awk "/ Test / (baskı $ 0)" $ echo "Bu bir denemedir" | awk "/ test / (yazdır $ 0)"

Normal ifadeler büyük / küçük harfe duyarlıdır

Büyük harfle başlayan "test" kelimesi metinde geçmediğinden, ilk normal ifade eşleşmedi. Büyük harfle yazılmış bir kelimeyi aramak için ayarlanmış olan ikincisi, akışta eşleşen bir dize buldu.

Normal ifadelerde yalnızca harfleri değil, boşlukları ve sayıları da kullanabilirsiniz:

$ echo "Bu yine bir test 2" | awk "/ test 2 / (0 $ yazdır)"

Boşluklar ve sayılar içeren bir metin parçası bulma

Boşluklar, normal ifade motoru tarafından normal karakterler olarak ele alınır.

Özel semboller

Normal ifadelerde farklı karakterler kullanırken akılda tutulması gereken birkaç nokta vardır. Örneğin, bir şablonda kullanmak için özel bir yaklaşım gerektiren bazı özel karakterler veya meta karakterler vardır. İşte buradalar:

.*^${}\+?|()
Şablonda bunlardan birine ihtiyaç duyulursa, ters eğik çizgi (ters eğik çizgi) - \\ ile öncelenmesi gerekecektir.

Örneğin, metinde bir dolar işareti bulmanız gerekirse, önünde bir çıkış karakteri ile şablona dahil edilmelidir. Diyelim ki aşağıdaki metni içeren myfile adında bir dosyanız var:

Cebimde 10 dolar var
Dolar işareti aşağıdaki gibi bir kalıp kullanılarak tespit edilebilir:

$ awk "/ \\ $ / (yazdır $ 0)" dosyam

Bir şablonda özel bir karakter kullanmak

Buna ek olarak, ters eğik çizgi de özel bir karakterdir, bu nedenle onu bir şablonda kullanmak istiyorsanız, ondan da kaçmanız gerekecektir. İki eğik çizgi gibi görünüyor:

$ echo "\\ özel bir karakterdir" | awk "/ \\\\ / (0 $ yazdır)"

Ters eğik çizgi kaçış

Eğik çizgi yukarıdaki özel karakterler listesinde yer almasa da, sed veya awk için yazılmış bir normal ifadede kullanmaya çalışmak bir hatayla sonuçlanacaktır:

$ echo "3/2" | awk "/// (0 $ yazdır)"

Bir şablonda yanlış eğik çizgi kullanımı

İhtiyaç duyarsanız, ayrıca taramanız gerekir:

$ echo "3/2" | awk "/ \\ // (0 $ yazdır)"

Eğik çizgiden kaçmak

Bağlantı sembolleri

Bir deseni bir metin dizesinin başına veya sonuna sabitlemek için iki özel karakter vardır. Kapak karakteri - ^, metin satırlarının başında görünen karakter dizilerini tanımlamanıza olanak tanır. Aradığınız desen dizenin başka bir yerinde görünüyorsa, normal ifade buna yanıt vermeyecektir. Bu sembolün kullanımı şuna benzer:

$ echo "likegeeks web sitesine hoş geldiniz" | awk "/ ^ likegeeks / (baskı $ 0)" $ echo "likegeeks web sitesi" | awk "/ ^ likegeeks / (baskı $ 0)"

Bir Satırın Başında Bir Desen Bulmak

^ Karakteri, bir dizenin başında bir örüntü aramak için kullanılırken, durum da dikkate alınır. Bunun işlemeyi nasıl etkilediğini görelim metin dosyası:

$ awk "/ ^ this / (yazdır $ 0)" dosyam


Bir dosyadaki metinde bir satırın başlangıcında bir model arayın

Sed ile, desenin herhangi bir yerine bir başlık yerleştirirseniz, diğer normal karakterler gibi işlem görür:

$ echo "Bu ^ bir testtir" | sed -n "/ s ^ / p"

Sed olarak bir desenin başında değil

Awk'de, aynı desen kullanılırken, verilen karakterin öncelenmesi gerekir:

$ echo "Bu ^ bir testtir" | awk "/ s \\ ^ / (0 $ yazdır)"

Awk'de bir şablonun başında değil

Satırın başında bulunan metin parçalarını aradık. Ya satırın sonunda bir şey bulmak istersen?

Satırın sonundaki bağlantı karakteri olan dolar işareti - $ bize bu konuda yardımcı olacaktır:

$ echo "Bu bir testtir" | awk "/ test $ / (baskı $ 0)"

Bir Satırın Sonundaki Metni Bulmak

Her iki bağlantı karakteri de aynı modelde kullanılabilir. İçeriği aşağıdaki şekilde gösterilen myfile dosyasını şu düzenli ifadeyi kullanarak işleyelim:

$ awk "/ ^ bu bir test $ / (baskı $ 0)" dosyam


Satırın başı ve sonu için özel karakterler kullanan desen

Gördüğünüz gibi, şablon yalnızca tam olarak eşleşen bir satıra tepki verdi verilen sıra semboller ve konumları.

Bağlantı karakterlerini kullanarak boş satırları şu şekilde filtreleyebilirsiniz:

$ awk "! / ^ $ / (baskı $ 0)" dosyam
Bu şablonda, olumsuzluk karakterini, ünlem işaretini kullandım -! ... Böyle bir kalıp kullanmak, dizenin başlangıcı ve sonu arasında hiçbir şey içermeyen dizeleri arar ve sayesinde ünlem işareti yalnızca bu desene uymayan çizgiler yazdırılır.

Nokta sembolü

Nokta, satır besleme dışında herhangi bir tek karakteri aramak için kullanılır. Myfile dosyasını, içeriği aşağıda gösterilen böyle bir düzenli ifadeye geçirelim:

$ awk "/.st/(print $ 0)" dosyam


Normal ifadelerde nokta kullanma

Çıktı verilerinden de görebileceğiniz gibi, dosyadan yalnızca ilk iki satır kalıba uyuyor, çünkü bu satırlar "st" karakterlerinin dizisini daha önce bir karakter daha içeriyor, üçüncü satır ise uygun bir sıra içermiyor ve dördüncüsü ise satırın en başında.

Karakter sınıfları

Nokta herhangi bir karakterle eşleşir, ancak ya aradığınız karakter kümesini daha esnek bir şekilde sınırlamanız gerekirse? Böyle bir durumda karakter sınıflarını kullanabilirsiniz.

Bu yaklaşım sayesinde, belirli bir kümedeki herhangi bir karakter için bir arama düzenleyebilirsiniz. Köşeli parantezler bir karakter sınıfını tanımlamak için kullanılır -:

$ awk "/ th / (baskı $ 0)" dosyam


Normal İfade Karakter Sınıfı Açıklama

Burada, önünde "o" karakteri veya "i" karakteri bulunan "th" karakterlerini arıyoruz.

Hem büyük hem de küçük harflerle başlayabilecek kelimeleri ararken sınıflar kullanışlıdır:

$ echo "bu bir testtir" | awk "/ onun bir test / (baskı $ 0)" $ echo "Bu bir testtir" | awk "/ onun bir test / (baskı $ 0)"

Küçük veya büyük harfle başlayabilen kelimeleri bulun

Karakter sınıfları harflerle sınırlı değildir. Burada başka semboller kullanılabilir. Hangi durumda sınıflara ihtiyaç duyulacağını önceden söyleyemezsiniz - hepsi çözülen soruna bağlıdır.

Karakter sınıflarının olumsuzlanması

Karakter sınıfları, yukarıda açıklanan zıt problemi çözmek için de kullanılabilir. Yani, sınıfa dahil olan sembolleri aramak yerine, sınıfa dahil olmayan her şey için bir arama düzenleyebilirsiniz. Normal bir ifadenin bu davranışını elde etmek için sınıfın karakter listesinin önüne bir ^ yerleştirilmelidir. Şöyle görünüyor:

$ awk "/ [^ oi] th / (yazdır $ 0)" dosyam


Bir sınıfın dışındaki karakterleri bulun

Bu durumda, "o" veya "i" bulunmayan "th" karakter dizileri bulunacaktır.

Karakter aralıkları

Karakter sınıflarında, karakter aralıklarını tire kullanarak tanımlayabilirsiniz:

$ awk "/ st / (baskı $ 0)" dosyam


Bir karakter sınıfındaki bir dizi karakteri açıklama

Bu örnekte, normal ifade, "e" ve "p" karakterleri arasında alfabetik sırada bulunan herhangi bir karakterden önce gelen "st" karakter dizisine yanıt verir.

Aralıklar ayrıca sayılardan da oluşturulabilir:

$ echo "123" | awk "//" $ echo "12a" | awk "//"

Herhangi üç sayıyı bulmak için normal ifade

Bir karakter sınıfına birkaç aralık dahil edilebilir:

$ awk "/ st / (baskı $ 0)" dosyam


Birden çok aralıktan oluşan bir karakter sınıfı

Bu normal ifade, önünde a-f ve m-z aralığındaki karakterlerin bulunduğu tüm dizelerle eşleşir.

Özel karakter sınıfları

BRE, normal ifadeleri yazarken kullanabileceğiniz özel karakter sınıflarına sahiptir:
  • [[: alpha:]] - herhangi bir büyük veya küçük harf alfabetik karakterle eşleşir.
  • [[: alnum:]] - herhangi bir alfasayısal karakterle, yani 0-9, A-Z, a-z aralığındaki karakterlerle eşleşir.
  • [[: boşluk:]] - boşluk ve sekmeyle eşleşir.
  • [[: digit:]] - 0'dan 9'a kadar herhangi bir dijital karakter.
  • [[: üst:]] - büyük harf alfabetik karakterler - A-Z.
  • [[: küçük:]] - küçük harf alfabetik karakterler - a-z.
  • [[: baskı:]] - herhangi bir yazdırılabilir karakterle eşleşir.
  • [[: punct:]] - noktalama işaretleriyle eşleşir.
  • [[: boşluk:]] - özellikle boşluk karakterleri - boşluk, tablo, NL, FF, VT, CR karakterleri.
Aşağıdaki gibi şablonlarda özel sınıflar kullanabilirsiniz:

$ echo "abc" | awk "/ [[: alpha:]] / ($ 0 yazdır)" $ echo "abc" | awk "/ [[: digit:]] / ($ 0 yazdır)" $ echo "abc123" | awk "/ [[: digit:]] / (0 $ yazdır)"


Normal ifadelerde özel karakter sınıfları

Yıldız sembolü

Kalıpta bir karakterden sonra bir yıldız işareti koyarsanız, karakter dizede herhangi bir sayıda göründüğünde normal ifadenin çalışacağı anlamına gelir - karakterin dizede bulunmadığı durum dahil.

$ echo "test" | awk "/ tes * t / (0 $ yazdır)" $ echo "tessst" | awk "/ tes * t / (0 $ yazdır)"


Normal ifadelerde * karakterini kullanma

Bu joker karakter genellikle sürekli olarak yazım hataları içeren kelimelerle veya farklı şekilde yazılabilen kelimeler için kullanılır:

$ echo "Yeşil rengi severim" | awk "/ colou * r / (baskı $ 0)" $ echo "Yeşil rengi severim" | awk "/ colou * r / (0 $ yazdır)"

Yazımları farklı olan bir kelimeyi arayın

Bu örnekte, aynı normal ifade hem "renk" hem de "renk" kelimesine yanıt verir. Bunun nedeni, yıldız işaretinin olduğu "u" sembolünün ya yok olabilmesi ya da arka arkaya birkaç kez görünebilmesidir.

Yıldız işaretinin özelliklerinden kaynaklanan bir başka kullanışlı özellik, onu bir nokta ile birleştirmektir. Bu kombinasyon, normal ifadenin herhangi bir sayıda karaktere yanıt vermesini sağlar:

$ awk "/this.*test/(print $ 0)" dosyam


Herhangi bir sayıda karaktere yanıt veren bir şablon

Bu durumda, "bu" ve "test" sözcükleri arasında kaç tane ve hangi karakter olduğu önemli değildir.

Yıldız işareti ayrıca karakter sınıflarıyla da kullanılabilir:

$ echo "st" | awk "/ s * t / (baskı $ 0)" $ echo "oturdu" | awk "/ s * t / (baskı $ 0)" $ echo "set" | awk "/ s * t / (0 $ yazdır)"


Karakter sınıflarında yıldız işareti kullanmak

Her üç örnekte de, normal ifade çalışır çünkü karakter sınıfından sonraki yıldız işareti, herhangi bir sayıda "a" veya "e" karakteri bulunursa veya bulunamazlarsa, dizenin belirtilen kalıpla eşleşeceği anlamına gelir.

POSIX ERE Normal İfadeler

Şablonlar pOSIX standardı Bazı Linux yardımcı programlarının desteklediği ERE'ler ek karakterler içerebilir. Daha önce de belirtildiği gibi, awk bu standardı destekler, ancak sed desteklemez.

Burada, kendi normal ifadelerinizi oluştururken kullanışlı olacak ERE desenlerinde en sık kullanılan sembollere bakacağız.

▍ Soru işareti

Soru işareti, önceki karakterin metinde bir kez görünebileceğini veya hiç görünmeyebileceğini belirtir. Bu karakter, yineleme meta karakterlerinden biridir. İşte bazı örnekler:

$ echo "tet" | awk "/ tes? t / (baskı $ 0)" $ echo "test" | awk "/ tes? t / (0 $ yazdır)" $ echo "tesst" | awk "/ tes? t / (0 $ yazdır)"


Normal ifadelerde soru işareti

Gördüğünüz gibi, üçüncü durumda, "s" harfi iki kez geçer, bu nedenle normal ifade "tesst" sözcüğüne tepki vermez.

Soru işareti, karakter sınıflarıyla da kullanılabilir:

$ echo "tst" | awk "/ t? st / (baskı $ 0)" $ echo "test" | awk "/ t? st / (baskı $ 0)" $ echo "zevk" | awk "/ t? st / (baskı $ 0)" $ echo "taest" | awk "/ t? st / (baskı $ 0)" $ echo "teest" | awk "/ t? st / (0 $ yazdır)"


Soru işareti ve karakter sınıfları

Dizede sınıftan hiç karakter yoksa veya bunlardan biri bir kez geçiyorsa, normal ifade çalışır, ancak sözcükte iki karakter görünür görünmez, sistem artık metindeki kalıp için bir eşleşme bulmaz.

▍ Artı sembolü

Desendeki artı simgesi, önceki karakter metinde bir veya birkaç kez geçerse normal ifadenin istenen ifadeyi bulacağını belirtir. Aynı zamanda, böyle bir yapı, bir sembolün yokluğuna tepki vermeyecektir:

$ echo "test" | awk "/ te + st / (baskı $ 0)" $ echo "teest" | awk "/ te + st / (baskı $ 0)" $ echo "tst" | awk "/ te + st / (0 $ yazdır)"


Artı normal ifadelerde oturum açın

Bu örnekte, bir sözcükte "e" yoksa, normal ifade motoru metinde bir eşleşme bulmayacaktır. Artı simgesi, yıldız ve soru işareti gibi görünmesini sağlayan karakter sınıflarıyla da çalışır:

$ echo "tst" | awk "/ t + st / (baskı $ 0)" $ echo "test" | awk "/ t + st / (baskı $ 0)" $ echo "teast" | awk "/ t + st / (baskı $ 0)" $ echo "teeast" | awk "/ t + st / (0 $ yazdır)"


Artı işareti ve karakter sınıfları

Bu durumda, dizge sınıftan herhangi bir karakter içeriyorsa, metnin kalıpla eşleştiği kabul edilecektir.

▍ Kıvrımlı parantezler

ERE kalıplarında kullanabileceğiniz süslü parantezler, yukarıda tartışılan karakterlere benzer, ancak önceki karakterin gerekli sayıda geçtiği yeri daha doğru bir şekilde belirlemenize olanak tanır. Sınırlama iki formatta belirtilebilir:
  • n - bulunacak tam oluşum sayısını belirten bir sayı
  • n, m - şu şekilde yorumlanan iki sayı: "en az n kez, ancak m'den fazla değil".
İşte ilk seçeneğin örnekleri:

$ echo "tst" | awk "/ te (1) st / (baskı $ 0)" $ echo "test" | awk "/ te (1) st / (baskı $ 0)"

Desenlerde kıvrımlı parantezler, kesin oluşum sayısını bulun

Awk'nin eski sürümlerinde, programın normal ifadelerdeki aralıkları tanıması için --re-interval komut satırı anahtarını kullanmanız gerekirdi, ancak daha yeni sürümlerde bu gerekli değildir.

$ echo "tst" | awk "/ te (1,2) st / (baskı $ 0)" $ echo "test" | awk "/ te (1,2) st / (baskı $ 0)" $ echo "teest" | awk "/ te (1,2) st / (baskı $ 0)" $ echo "teeest" | awk "/ te (1,2) st / (baskı $ 0)"


Küme parantezinde belirtilen aralık

Bu örnekte, "e" karakteri satırda 1 veya 2 kez görünmelidir, ardından normal ifade metne tepki verecektir.

Kaşlı ayraçlar, karakter sınıflarıyla da kullanılabilir. Zaten bildiğiniz ilkeler şunlardır:

$ echo "tst" | awk "/ t (1,2) st / (baskı $ 0)" $ echo "test" | awk "/ t (1,2) st / (baskı $ 0)" $ echo "teest" | awk "/ t (1,2) st / (baskı $ 0)" $ echo "teeast" | awk "/ t (1,2) st / (baskı $ 0)"


Kıvırcık ayraçlar ve karakter sınıfları

Şablon, bir veya iki kez "a" karakterini veya "e" karakterini içeriyorsa metne tepki verecektir.

▍ Boolean "veya" karakteri

Sembol | - dikey çubuk, normal ifadelerde mantıksal "veya" anlamına gelir. Böyle bir işaretle ayrılmış birkaç parça içeren normal bir ifadeyi işlerken, motor, parçalardan herhangi biriyle eşleşiyorsa ayrıştırılmış metnin uygun olduğunu düşünecektir. İşte bir örnek:

$ echo "Bu bir testtir" | awk "/ test | sınav / (baskı $ 0)" $ echo "Bu bir sınavdır" | awk "/ test | sınav / (baskı $ 0)" $ echo "Bu başka bir şey" | awk "/ test | sınav / (baskı $ 0)"


Boole veya normal ifadelerde

Bu örnekte, normal ifade, metni "test" veya "sınav" sözcüklerini arayacak şekilde yapılandırılmıştır. Şablon parçaları ve ayırma sembolü arasında | boşluk olmamalıdır.

Normal ifade parçaları, parantezler kullanılarak gruplanabilir. Belirli bir karakter dizisini gruplandırırsanız, sistem tarafından sıradan bir karakter olarak algılanacaktır. Yani, örneğin, ona tekrar metakarakterleri uygulamak mümkün olacaktır. Şöyle görünüyor:

$ echo "Beğen" | awk "/ Beğen (Geeks)? / (yazdır $ 0)" $ echo "LikeGeeks" | awk "/ Beğen (Geeks)? / (yazdır $ 0)"


Normal İfade Parçalarını Gruplama

Bu örneklerde, "Geeks" sözcüğü parantez içine alınmış ve ardından bir soru işareti verilmiştir. Bir soru işaretinin "0 veya 1 tekrar" anlamına geldiğini hatırlayın, sonuç olarak normal ifade hem "Beğen" dizesine hem de "LikeGeeks" dizesine yanıt verir.

Pratik örnekler

Artık normal ifadelerin temellerini ele aldığımıza göre, onlarla yararlı bir şeyler yapma zamanı.

▍Dosyaların sayısını saymak

Yazılan dizinlerdeki dosyaları sayan bir bash betiği yazalım. Çevre değişkeni PATH. Bunu yapmak için, önce dizinlere giden yolların bir listesini oluşturmanız gerekecektir. İki nokta üst üste boşlukları yerine sed ile yapalım:

$ echo $ PATH | sed "s /: / / g"
Değiştir komutu, metin arama kalıpları olarak normal ifadeleri destekler. Bu durumda, her şey son derece basittir, iki nokta üst üste simgesi arıyoruz, ancak burada kimse başka bir şey kullanmayı zahmet etmiyor - hepsi belirli göreve bağlı.
Şimdi, ortaya çıkan listeyi bir döngü içinde gözden geçirmeniz ve oradaki dosyaların sayısını saymak için gerekli eylemleri gerçekleştirmeniz gerekir. Komut dosyasının genel şeması aşağıdaki gibi olacaktır:

Mypath \u003d $ (echo $ PATH | sed "s /: / / g") $ mypath içindeki dizin için yapıldı
Şimdi her dizindeki dosya sayısı hakkında bilgi almak için ls komutunu kullanarak komut dosyasının tam metnini yazalım:

#! / bin / bash mypath \u003d $ (echo $ PATH | sed "s /: / / g") sayı \u003d 0 $ mypath dizini için kontrol et \u003d $ (ls $ dizini) $ check do count \u003d $ [$ count + 1] tamamlandı echo "$ dizin - $ sayım" sayı \u003d 0 bitti
Komut dosyasını çalıştırdığınızda, PATH'deki bazı dizinlerin olmadığı ortaya çıkabilir, ancak bu, var olan dizinlerdeki dosyaları saymasını engellemeyecektir.


Dosyaları saymak

Bu örneğin ana değeri, aynı yaklaşımı kullanarak çok daha karmaşık problemleri çözebileceğiniz gerçeğinde yatmaktadır. Hangisi tam olarak ihtiyaçlarınıza bağlıdır.

▍E-posta adreslerini kontrol etme

URL’leri doğrulamanıza izin veren çok sayıda normal ifade koleksiyonuna sahip web siteleri vardır. e-posta, telefon numaraları vb. Bununla birlikte, hazır olanı almak bir şeydir ve kendi başına bir şey yaratmak başka bir şeydir. Bu nedenle, e-posta adreslerini doğrulamak için normal bir ifade yazalım. İlk verileri analiz ederek başlayalım. Örneğin, işte belirli bir adres:

[e-posta korumalı]
Kullanıcı adı, kullanıcı adı, alfasayısal ve diğer bazı karakterlerden oluşabilir. Yani bir nokta, tire, alt çizgi ve artı işaretidir. Kullanıcı adının ardından bir @ işareti gelir.

Bu bilgiyle donanmış olarak, normal ifadeyi kullanıcı adını doğrulamaya yarayan sol tarafından oluşturmaya başlayalım. İşte elimizde ne var:

^(+)@
Bu normal ifade şu şekilde okunabilir: "Bir satırın başında, köşeli parantez içinde belirtilen gruptan en az biri ve ardından bir @ işareti bulunmalıdır."

Şimdi - ana bilgisayar adı kuyruğu ana bilgisayar adıdır. Kullanıcı adı için de aynı kurallar geçerlidir, dolayısıyla bunun şablonu şu şekilde görünecektir:

(+)
alan adı Üst düzey özel kurallara tabidir. Yalnızca en az iki (örneğin, bu tür alan adları genellikle bir ülke kodu içerir) ve beşten fazla olmaması gereken alfabetik karakterler olabilir. Bütün bunlar, adresin son bölümünü kontrol etmek için şablonun şu şekilde olacağı anlamına gelir:

\.({2,5})$
Bunu şu şekilde okuyabilirsiniz: "Önce bir nokta olmalı, sonra - 2 ila 5 alfabetik karakter ve ondan sonra satır bitiyor".

Normal ifadenin ayrı bölümleri için şablonlar hazırladıktan sonra, onları bir araya getirelim:

^(+)@(+)\.({2,5})$
Şimdi sadece ne olduğunu test etmek için kalıyor:

$ echo " [e-posta korumalı]"| awk" / ^(+)@(+)\\.((2,5))$/(print $ 0) "$ echo" [e-posta korumalı]"| awk" / ^(+)@(+)\\.((2,5))$/(print 0 $) "


Normal İfadeler Kullanarak Bir E-posta Adresini Doğrulama

Awk'a aktarılan metnin ekranda görüntülenmesi, sistemin içindeki e-posta adresini tanıdığı anlamına gelir.

Sonuç

Makalenin başında tanıştığınız e-posta adreslerini doğrulamak için kullanılan normal ifade o zaman tamamen anlaşılmaz görünüyorsa, artık anlamsız bir karakter kümesine benzemeyeceğini umuyoruz. Bu doğruysa, bu malzeme amacını yerine getirmiştir. Aslında, normal ifadeler tüm hayatınız boyunca ele alınabilecek bir konudur, ancak tartıştığımız çok az şey bile, metinleri oldukça gelişmiş işleyen senaryolar yazmanıza yardımcı olabilir.

Bu dizide genellikle çok gösterdik basit örnekler birkaç satırlık bash betikleri. Bir dahaki sefere daha büyük bir şeye bakalım.

Sevgili okuyucular! Komut satırı betiklerinde metin işlerken normal ifadeler kullanıyor musunuz?

İyi vakit geçirin konuklar!

Bugünün makalesinde şu kadar büyük bir konuya değinmek istiyorum: Düzenli ifadeler... Bence herkes normal ifadeler konusunun (argo normal ifadeler olarak adlandırıldığı için) bir gönderinin hacmi içinde çok büyük olduğunu biliyor. Bu nedenle kısaca ama olabildiğince açık bir şekilde düşüncelerimi bir araya toplayıp size aktarmaya çalışacağım.

Başlangıç \u200b\u200bolarak, normal ifadelerin birkaç çeşidi vardır:

1. Geleneksel normal ifadeler (aynı zamanda temel, temel ve temel normal ifadeler (BRE))

  • bu ifadelerin sözdiziminin eski olduğu belirlendi, ancak yine de hala yaygın ve birçok UNIX aracı tarafından kullanılıyor
  • Temel normal ifadeler aşağıdaki meta karakterleri içerir (aşağıdaki anlamlarına bakın):
    • \\ (\\) - () için orijinal (genişletilmiş)
    • \\ (\\) - () için orijinal (genişletilmiş)
    • \n nerede n - 1'den 9'a kadar sayı
  • Bu meta karakterleri kullanmanın özellikleri:
    • Yıldız işareti, tek bir karakterle eşleşen ifadeyi takip etmelidir. Misal: *.
    • İfade \\ ( blok\\) * geçersiz kabul edilmelidir. Bazı durumlarda, dizenin sıfır veya daha fazla tekrarıyla eşleşir. blok ... Diğerlerinde dizeyle eşleşir blok* .
    • Bir karakter sınıfı içinde, özel karakter anlamları genellikle göz ardı edilir. Özel durumlar:
    • Bir kümeye ^ karakteri eklemek için oraya ilk yerleştirilmemelidir.
    • Bir sembol eklemek için - bir kümeye, oraya ilk veya son olarak yerleştirilmelidir. Örneğin:
      • harfler, sayılar, eksi ve ayırıcı nokta içerebilen DNS adı kalıbı: [-0-9a-zA-Z.];
      • eksi ve rakam dışında herhangi bir karakter: [^ -0-9].
    • Kümeye [veya] karakterini eklemek için önce oraya yerleştirilmelidir. Örneğin:
      • eşleşir], [, a veya b.

2. Genişletilmiş normal ifadeler (onlar genişletilmiş normal ifadeler (ERE))

  • Bu ifadelerin sözdizimi, ana ifadelerle aynıdır, ancak şunlar hariç:
    • () Ve () meta karakterleri için ters eğik çizgi kullanımı kaldırıldı.
    • Bir meta karakterin önündeki ters eğik çizgi, özel anlamını iptal eder.
    • Teorik olarak reddedildi düzensiz inşaat \\ n .
    • Metakarakterler eklendi +,? , | ...

3. Perl Uyumlu Normal İfadeler(onlar Perl uyumlu normal ifadeler (PCRE))

  • pOSIX ERE'den bile daha zengin ve aynı zamanda öngörülebilir bir sözdizimine sahiptir, bu nedenle uygulamalar tarafından sıklıkla kullanılır.

Düzenli ifadeler oluşmaktadırşablonlar veya daha doğrusu bir düzen oluşturmak arama. Şablon oluşur nın-nin kurallaroluşan aramalar karakterlerve meta karakterler.

Arama kuralları aşağıdakiler tarafından tanımlanmıştır operasyonlar:

Numaralandırma |

Dikey çubuk (|) geçerli seçenekleri ayırır, diyebiliriz - mantıksal OR. Örneğin, "gri | gri" eşleşir gri veya gri.

Gruplama veya birleştirme ()

Yuvarlak parantezler operatörlerin kapsamını ve önceliğini tanımlamak için kullanılır. Örneğin, "gri | gri" ve "gr (a | e) y" farklı modellerdir, ancak her ikisi de içeren bir set tanımlar gri ve gri.

Miktar belirleme ()? * +

Nicelik belirteci bir karakter veya gruptan sonra kaç kez öncekiifade oluşabilir.

genel ifade, tekrarlar olabilir m'den n'ye kadar.

genel ifade m veya daha fazla tekrar.

genel ifade n tekrardan fazla değil.

pürüzsüz n tekrar.

Soru işaretianlamına geliyor 0 veya 1 kez, aynı {0,1} ... Örneğin, "colou? R" eşleşir ve renkve renk.

Staranlamına geliyor 0, 1 veya herhangi bir sayı zamanlar ( {0,} ). Örneğin, "go * gle" eşleşir kıkırdamak, gogle, google ve benzeri.

Bir artıanlamına geliyor en az 1 zamanlar ( {1,} ). Örneğin, "git + gle" eşleşir gogle, google ve benzeri (ama değil kıkırdamak).

Bu normal ifadeler için özel sözdizimi uygulamaya bağlıdır. (yani içinde temel normal ifadeler semboller (ve)- ters eğik çizgi ile kaçtı)

MetakarakterlerBasit bir ifadeyle, bunlar gerçek anlamlarına, yani bir sembole karşılık gelmeyen sembollerdir. (nokta) bir nokta değil, herhangi bir karakter vb. lütfen meta karakterleri ve anlamlarını öğrenin:

. karşılık gelir birherhangi bir karakter
[bir şey] Uysal herhangi bir bekarparantez içinde bir karakter. Bu durumda: "-" karakteri yalnızca açılıştan hemen sonra veya kapanış parantezinden önce yer alıyorsa yorumlanır: veya [-abc]. Aksi takdirde, bir karakter aralığını belirtir, örneğin "a", "b" veya "c" ile eşleşir. Latin alfabesinin küçük harfleriyle eşleşir. Bu gösterimler birleştirilebilir ve birleştirilebilir: a, b, c, q, r, s, t, u, v, w, x, y, z ile eşleşir. "[" Veya "]" karakterlerini eşleştirmek için, kapanış parantezinin açılış karakterinden sonraki ilk karakterdi: "]", "[", "a" veya "b" ile eşleşir. Köşeli parantezler içindeki değerin önünde ^ işareti varsa, ifadenin değeri eşleşir tek karakter bunların arasından parantez içinde olmayanlar... Örneğin, [^ abc] "a", "b" veya "c" dışındaki herhangi bir karakterle eşleşir. [^ a-z], Latin küçük harf karakterleri dışındaki herhangi bir karakterle eşleşir.
^ Metnin başıyla (veya satır modundaysa herhangi bir satırın başlangıcıyla) eşleşir.
$ Metnin sonuyla (veya satır içi moddaysa herhangi bir satırın sonuyla) eşleşir.
\\ (\\) veya () Daha sonra kullanılabilecek bir "işaretli alt ifade" (gruplanmış bir ifade) bildirir (sonraki öğeye bakın: \\ n). "İşaretli alt ifade" de bir "blok" tur. Diğer operatörlerden farklı olarak, bu (geleneksel sözdiziminde) bir ters eğik çizgi gerektirir, genişletilmiş durumda ve Perl \\ - gerekli değildir.
\n Nerede n - bu 1'den 9'a kadar bir sayıdır; karşılık gelir nişaretli alt ifade (örneğin (abcd) \\ 0, yani abcd karakterleri sıfır ile işaretlenmiştir). Bu yapı teorik olarak düzensiz, genişletilmiş normal ifade sözdiziminde kabul edilmedi.
*
  • Startek bir karakterle eşleşen bir ifadeden sonra sıfırveya daha kopyalarbu (önceki) ifadenin. Örneğin, "*" boş bir dizeyle eşleşir, "x", "y", "zx", "zyx" vb.
  • \n* nerede n 1'den 9'a kadar bir rakamdır, eşleşmek için sıfır veya daha fazla eşleşmeyle eşleşir nth işaretli alt ifade. Örneğin, "\\ (a. \\) C \\ 1 *", "abcab" ve "abcaba" ile eşleşir ancak "abcac" ile eşleşmez.

"\\ (" Ve "\\)" ve ardından "*" ile çevrili bir ifade geçersiz sayılmalıdır. Bazı durumlarda, parantez içine alınmış dizenin sıfır veya daha fazla oluşumuyla eşleşir. Diğerlerinde, "*" karakteri verildiğinde parantez içindeki ifadeyle eşleşir.

\{x,y\} İkincisiyle eşleşir ( gelecek) en azından meydana gelen bir bloğa x ve daha fazla yok y zaman. Örneğin, "a \\ (3,5 \\)", "aaa", "aaaa" veya "aaaaa" ile eşleşir. Diğer operatörlerin aksine, bu (geleneksel sözdiziminde) ters eğik çizgi gerektirir.
.* Normal ifadenin iki bölümü arasında herhangi bir sayıda karakterin atanması.

Metakarakterler, farklı eşleşmeler kullanmamıza yardımcı olur. Ancak bir meta karakteri normal bir karakterle, yani [(köşeli parantez) karakterini köşeli parantez değeri olarak nasıl temsil edersiniz? Sadece:

  • öncesinde olmalıdır ( kalkan) meta karakter (. * + \\? ()) ters eğik çizgi. Örneğin \\. veya \\ [

Bazı karakter kümelerinin tanımını basitleştirmek için sözde birleştirildi. karakter sınıfları ve kategorileri. POSIX, aşağıdaki tabloda gösterildiği gibi, bazı sınıfların ve sembol kategorilerinin bildirimini standartlaştırmıştır:

POSIX sınıfı benzer şekilde atama
[: üst:] büyük harf karakterleri
[: alt:] küçük harfli karakterler
[: alpha:] büyük ve küçük harf karakterleri
[: alnum:] sayılar, büyük ve küçük harf karakterler
[: hane:] rakamlar
[: xdigit:] onaltılık rakamlar
[: nokta:] [.,!?:…] noktalama işaretleri
[: boş:] [\\ t] boşluk ve SEKME
[: Uzay:] [\\ t \\ n \\ r \\ f \\ v] karakterleri atla
[: cntrl:] kontrol sembolleri
[: grafik:] [^ \\ t \\ n \\ r \\ f \\ v] baskı sembolleri
[: Yazdır:] [^ \\ t \\ n \\ r \\ f \\ v] karakterleri yazdır ve atla

Normal ifadede şöyle bir şey vardır:

Açgözlülük normal ifadesi

Bunu olabildiğince açık bir şekilde anlatmaya çalışacağım. Diyelim ki her şeyi bulmak istiyoruz HTML etiketleri bazı metinlerde. Görevi yerelleştirdikten sonra, aradaki değerleri bulmak istiyoruz< и >aynı parantezlerle birlikte. Ama etiketlerin sahip olduğunu biliyoruz farklı uzunluk ve etiketlerin kendileri, en az 50 parça. Hepsini meta karakterlere ekleyerek listelemek çok zaman alan bir iştir. Ancak, dizedeki herhangi bir sayıda karakteri karakterize eden bir ifademiz olduğunu biliyoruz. * (Nokta yıldız işareti). Bu ifadeyi kullanarak metinde bulmaya çalışacağız (

Yani, LSI MegaRAID denetleyicisinde 10/50 RAID düzeyi nasıl oluşturulur (ayrıca şunlar için de geçerlidir: Intel SRCU42x, Intel SRCS16):

) arasındaki tüm değerler< и >... Sonuç olarak, TÜM dizge bu ifadeyle eşleşecektir. neden, çünkü normal ifade GREEDY'dir ve aradaki TÜM sayıda karakteri yakalamaya çalışır.< и >sırasıyla, tüm satır başlangıcı < p\u003e Yani ...ve biten ...> bu kurala ait olacak!

Umarım bu açgözlülüğün ne olduğuna dair bir örnektir. Bu açgözlülükten kurtulmak için aşağıdaki yolu takip edebilirsiniz:

  • sembolleri hesaba katın, değil istenen kalıbı eşleştirme (örneğin:<[^>] *\u003e yukarıdaki durum için)
  • bir nicelik belirtecinin açgözlü olmayan tanımını ekleyerek açgözlülükten kurtulun:
    • *? - "açgözlü değil" ("tembel") eşdeğeri *
    • +? - "açgözlü değil" ("tembel") eşdeğeri +
    • (n,)? - "açgözlü değil" ("tembel") (n,) ile eşdeğerdir
    • . *? - "açgözlü değil" ("tembel") eşdeğeri. *

Yukarıdakilerin hepsini tamamlamak istiyorum genişletilmiş normal ifade sözdizimi ile:

POSIX'teki normal ifadeler geleneksel Unix sözdizimine benzer, ancak bazı meta karakterlerin eklenmesiyle:

Bir artıbelirtir öncekisembol veya gruptekrar edilebilir bir veya daha fazla kez... Yıldız işaretinin aksine, en az bir tekrar gerekir.

Soru işareti yapar öncekiisteğe bağlı karakter veya grup. Başka bir deyişle, karşılık gelen satırda olmayabilir veya mevcut olabilir pürüzsüz birzaman.

Dikey çubukhisse alternatif seçenekler düzenli ifadeler. Bir sembol iki alternatifi tanımlar, ancak bunlardan daha fazlası olabilir, daha fazla dikey çubuk kullanmak yeterlidir. Bu operatörün mümkün olduğunca fazla ifade kullandığını unutmayın. Bu nedenle, alternatif operatör genellikle parantez içinde kullanılır.

Ters eğik çizgi kullanımı da iptal edildi: \\ (... \\) (...) ve \\ (... \\) (...) olur.

Gönderinin sonunda, normal ifadenin kullanımına ilişkin bazı örnekler aşağıda verilmiştir:

$ kedi metni1 1 elma 2 armut 3 muz $ grep p metin1 1 elma 2 armut $ grep "pp *" metin1 1 elma 2 armut $ kedi metni1 | grep "l \\ | n" 1 elma 3 muz $ echo -e "burada \\ n * bul" | grep "\\ *" * burada $ grep "pl \\ ?. * r" text1 # p, r 2 armut içeren satırlar $ grep "a .." text1 # satır ve ardından en az 2 karakter 1 elma 3 muz $ grep "" text1 # 3 veya p içeren satırları ara 1 elma 2 armut 3 muz $ echo -e "burada \\ nbir yerde \\ n bul." | grep "[. *]" * burada bir yerde..ad] $ echo -e "123 \\ n456 \\ n789 \\ n0" | grep "" 123 456 789 $ sed -e "/\\(a.*a\\)\\\\\\(p.*p\\)/s/a/A/g" text1 # tüm satırlarda a yerine A ile a gelir sonra a gelir veya sonra p gelir p 1 Elma 2 armut 3 bAnAnA * \\ ./ SON SÖZCÜK./g "İlk. SON SÖZ. Bu SON SÖZCÜK.

Saygılarımızla, Mc.Sim!

Bugünün makalesinde şu kadar büyük bir konuya değinmek istiyorum: Düzenli ifadeler... Bence herkes normal ifadeler konusunun (argo normal ifadeler olarak adlandırıldığı için) bir gönderinin hacmi içinde çok büyük olduğunu biliyor.

Başlangıç \u200b\u200bolarak, normal ifadelerin birkaç çeşidi vardır:

1. Geleneksel normal ifadeler (aynı zamanda temel, temel ve temel normal ifadeler (BRE))

  • bu ifadelerin sözdiziminin eski olduğu belirlendi, ancak yine de hala yaygın ve birçok UNIX aracı tarafından kullanılıyor
  • Temel normal ifadeler aşağıdaki meta karakterleri içerir (aşağıdaki anlamlarına bakın):
    • \\ (\\) - () için orijinal (genişletilmiş)
    • \\ (\\) - () için orijinal (genişletilmiş)
    • \n nerede n - 1'den 9'a kadar sayı
  • Bu meta karakterleri kullanmanın özellikleri:
    • Yıldız işareti, tek bir karakterle eşleşen ifadeyi takip etmelidir. Misal: *.
    • İfade \\ ( blok\\) * geçersiz kabul edilmelidir. Bazı durumlarda, dizenin sıfır veya daha fazla tekrarıyla eşleşir. blok ... Diğerlerinde dizeyle eşleşir blok* .
    • Bir karakter sınıfı içinde, özel karakter anlamları genellikle göz ardı edilir. Özel durumlar:
    • Bir kümeye ^ karakteri eklemek için oraya ilk yerleştirilmemelidir.
    • Bir sembol eklemek için - bir kümeye, oraya ilk veya son olarak yerleştirilmelidir. Örneğin:
      • harfler, sayılar, eksi ve ayırıcı nokta içerebilen DNS adı kalıbı: [-0-9a-zA-Z.];
      • eksi ve rakam dışında herhangi bir karakter: [^ -0-9].
    • Kümeye [veya] karakterini eklemek için önce oraya yerleştirilmelidir. Örneğin:
      • eşleşir], [, a veya b.

2. Genişletilmiş normal ifadeler (onlar genişletilmiş normal ifadeler (ERE))

  • Bu ifadelerin sözdizimi, ana ifadelerle aynıdır, ancak şunlar hariç:
    • () Ve () meta karakterleri için ters eğik çizgi kullanımı kaldırıldı.
    • Bir meta karakterin önündeki ters eğik çizgi, özel anlamını iptal eder.
    • Teorik olarak reddedildi düzensiz inşaat \\ n .
    • Metakarakterler eklendi +,? , | ...

3. Perl Uyumlu Normal İfadeler(onlar Perl uyumlu normal ifadeler (PCRE))

  • pOSIX ERE'den bile daha zengin ve aynı zamanda öngörülebilir bir sözdizimine sahiptir, bu nedenle uygulamalar tarafından sıklıkla kullanılır.

Düzenli ifadeler oluşmaktadırşablonlar veya daha doğrusu bir düzen oluşturmak arama. Şablon oluşur nın-nin kurallaroluşan aramalar karakterlerve meta karakterler.

Arama kuralları aşağıdakiler tarafından tanımlanmıştır operasyonlar:

Numaralandırma |

Dikey çubuk (|) geçerli seçenekleri ayırır, diyebiliriz - mantıksal OR. Örneğin, "gri | gri" eşleşir gri veya gri.

Gruplama veya birleştirme ()

Yuvarlak parantezler operatörlerin kapsamını ve önceliğini tanımlamak için kullanılır. Örneğin, "gri | gri" ve "gr (a | e) y" farklı modellerdir, ancak her ikisi de içeren bir set tanımlar gri ve gri.

Miktar belirleme ()? * +

Nicelik belirteci bir karakter veya gruptan sonra kaç kez öncekiifade oluşabilir.

genel ifade, tekrarlar olabilir m'den n'ye kadar.

genel ifade m veya daha fazla tekrar.

genel ifade n tekrardan fazla değil.

pürüzsüz n tekrar.

Soru işaretianlamına geliyor 0 veya 1 kez, aynı {0,1} ... Örneğin, "colou? R" eşleşir ve renkve renk.

Staranlamına geliyor 0, 1 veya herhangi bir sayı zamanlar ( {0,} ). Örneğin, "go * gle" eşleşir kıkırdamak, gogle, google ve benzeri.

Bir artıanlamına geliyor en az 1 zamanlar ( {1,} ). Örneğin, "git + gle" eşleşir gogle, google ve benzeri (ama değil kıkırdamak).

Bu normal ifadeler için özel sözdizimi uygulamaya bağlıdır. (yani içinde temel normal ifadeler semboller (ve)- ters eğik çizgi ile kaçtı)

MetakarakterlerBasit bir ifadeyle, bunlar gerçek anlamlarına, yani bir sembole karşılık gelmeyen sembollerdir. (nokta) bir nokta değil, herhangi bir karakter vb. lütfen meta karakterleri ve anlamlarını öğrenin:

. karşılık gelir birherhangi bir karakter
[bir şey] Uysal herhangi bir bekarparantez içinde bir karakter. Bu durumda: "-" karakteri yalnızca açılıştan hemen sonra veya kapanış parantezinden önce yer alıyorsa yorumlanır: veya [-abc]. Aksi takdirde, bir karakter aralığını belirtir, örneğin "a", "b" veya "c" ile eşleşir. Latin alfabesinin küçük harfleriyle eşleşir. Bu gösterimler birleştirilebilir ve birleştirilebilir: a, b, c, q, r, s, t, u, v, w, x, y, z ile eşleşir. "[" Veya "]" karakterlerini eşleştirmek için, kapanış parantezinin açılış karakterinden sonraki ilk karakterdi: "]", "[", "a" veya "b" ile eşleşir. Köşeli parantezler içindeki değerin önünde ^ işareti varsa, ifadenin değeri eşleşir tek karakter bunların arasından parantez içinde olmayanlar... Örneğin, [^ abc] "a", "b" veya "c" dışındaki herhangi bir karakterle eşleşir. [^ a-z], Latin küçük harf karakterleri dışındaki herhangi bir karakterle eşleşir.
^ Metnin başıyla (veya satır modundaysa herhangi bir satırın başlangıcıyla) eşleşir.
$ Metnin sonuyla (veya satır içi moddaysa herhangi bir satırın sonuyla) eşleşir.
\\ (\\) veya () Daha sonra kullanılabilecek bir "işaretli alt ifade" (gruplanmış bir ifade) bildirir (sonraki öğeye bakın: \\ n). "İşaretli alt ifade" de bir "blok" tur. Diğer operatörlerden farklı olarak, bu (geleneksel sözdiziminde) bir ters eğik çizgi gerektirir, genişletilmiş durumda ve Perl \\ - gerekli değildir.
\n Nerede n - bu 1'den 9'a kadar bir sayıdır; karşılık gelir nişaretli alt ifade (örneğin (abcd) \\ 0, yani abcd karakterleri sıfır ile işaretlenmiştir). Bu yapı teorik olarak düzensiz, genişletilmiş normal ifade sözdiziminde kabul edilmedi.
*
  • Startek bir karakterle eşleşen bir ifadeden sonra sıfırveya daha kopyalarbu (önceki) ifadenin. Örneğin, "*" boş bir dizeyle eşleşir, "x", "y", "zx", "zyx" vb.
  • \n* nerede n 1'den 9'a kadar bir rakamdır, eşleşmek için sıfır veya daha fazla eşleşmeyle eşleşir nth işaretli alt ifade. Örneğin, "\\ (a. \\) C \\ 1 *", "abcab" ve "abcaba" ile eşleşir ancak "abcac" ile eşleşmez.

"\\ (" Ve "\\)" ve ardından "*" ile çevrili bir ifade geçersiz sayılmalıdır. Bazı durumlarda, parantez içine alınmış dizenin sıfır veya daha fazla oluşumuyla eşleşir. Diğerlerinde, "*" karakteri verildiğinde parantez içindeki ifadeyle eşleşir.

\{x,y\} İkincisiyle eşleşir ( gelecek) en azından meydana gelen bir bloğa x ve daha fazla yok y zaman. Örneğin, "a \\ (3,5 \\)", "aaa", "aaaa" veya "aaaaa" ile eşleşir. Diğer operatörlerin aksine, bu (geleneksel sözdiziminde) ters eğik çizgi gerektirir.
.* Normal ifadenin iki bölümü arasında herhangi bir sayıda karakterin atanması.

Metakarakterler, farklı eşleşmeler kullanmamıza yardımcı olur. Ancak bir meta karakteri normal bir karakterle, yani [(köşeli parantez) karakterini köşeli parantez değeri olarak nasıl temsil edersiniz? Sadece:

  • öncesinde olmalıdır ( kalkan) meta karakter (. * + \\? ()) ters eğik çizgi. Örneğin \\. veya \\ [

Bazı karakter kümelerinin tanımını basitleştirmek için sözde birleştirildi. karakter sınıfları ve kategorileri. POSIX, aşağıdaki tabloda gösterildiği gibi, bazı sınıfların ve sembol kategorilerinin bildirimini standartlaştırmıştır:

POSIX sınıfı benzer şekilde atama
[: üst:] büyük harf karakterleri
[: alt:] küçük harfli karakterler
[: alpha:] büyük ve küçük harf karakterleri
[: alnum:] sayılar, büyük ve küçük harf karakterler
[: hane:] rakamlar
[: xdigit:] onaltılık rakamlar
[: nokta:] [.,!?:…] noktalama işaretleri
[: boş:] [\\ t] boşluk ve SEKME
[: Uzay:] [\\ t \\ n \\ r \\ f \\ v] karakterleri atla
[: cntrl:] kontrol sembolleri
[: grafik:] [^ \\ t \\ n \\ r \\ f \\ v] baskı sembolleri
[: Yazdır:] [^ \\ t \\ n \\ r \\ f \\ v] karakterleri yazdır ve atla

Normal ifadede şöyle bir şey vardır:

Açgözlülük normal ifadesi

Bunu olabildiğince açık bir şekilde anlatmaya çalışacağım. Diyelim ki bir metinde tüm HTML etiketlerini bulmak istiyoruz. Görevi yerelleştirdikten sonra, aradaki değerleri bulmak istiyoruz< и >aynı parantezlerle birlikte. Ancak etiketlerin farklı uzunluklara sahip olduğunu ve etiketlerin kendilerinin en az 50 parça olduğunu biliyoruz. Hepsini listelemek için onları meta karakterlere eklemek çok zaman alan bir iştir. Ancak, dizedeki herhangi bir sayıda karakteri karakterize eden bir ifademiz olduğunu biliyoruz. * (Nokta yıldız işareti). Bu ifadeyi kullanarak metinde bulmaya çalışacağız (

Yani, LSI MegaRAID denetleyicisinde 10/50 RAID düzeyi nasıl oluşturulur (ayrıca şunlar için de geçerlidir: Intel SRCU42x, Intel SRCS16):

) arasındaki tüm değerler< и >... Sonuç olarak, TÜM dizge bu ifadeyle eşleşecektir. neden, çünkü normal ifade GREEDY'dir ve aradaki TÜM sayıda karakteri yakalamaya çalışır.< и >sırasıyla, tüm satır başlangıcı < p\u003e Yani ...ve biten ...> bu kurala ait olacak!

Umarım bu açgözlülüğün ne olduğuna dair bir örnektir. Bu açgözlülükten kurtulmak için aşağıdaki yolu takip edebilirsiniz:

  • sembolleri hesaba katın, değil istenen kalıbı eşleştirme (örneğin:<[^>] *\u003e yukarıdaki durum için)
  • bir nicelik belirtecinin açgözlü olmayan tanımını ekleyerek açgözlülükten kurtulun:
    • *? - "açgözlü değil" ("tembel") eşdeğeri *
    • +? - "açgözlü değil" ("tembel") eşdeğeri +
    • (n,)? - "açgözlü değil" ("tembel") (n,) ile eşdeğerdir
    • . *? - "açgözlü değil" ("tembel") eşdeğeri. *

Yukarıdakilerin hepsini tamamlamak istiyorum genişletilmiş normal ifade sözdizimi ile:

POSIX'teki normal ifadeler geleneksel Unix sözdizimine benzer, ancak bazı meta karakterlerin eklenmesiyle:

Bir artıbelirtir öncekisembol veya gruptekrar edilebilir bir veya daha fazla kez... Yıldız işaretinin aksine, en az bir tekrar gerekir.

Soru işareti yapar öncekiisteğe bağlı karakter veya grup. Başka bir deyişle, karşılık gelen satırda olmayabilir veya mevcut olabilir pürüzsüz birzaman.

Dikey çubukalternatif normal ifadeleri ayırır. Bir sembol iki alternatifi tanımlar, ancak bunlardan daha fazlası olabilir, daha fazla dikey çubuk kullanmak yeterlidir. Bu operatörün mümkün olduğunca fazla ifade kullandığını unutmayın. Bu nedenle, alternatif operatör genellikle parantez içinde kullanılır.

Ters eğik çizgi kullanımı da iptal edildi: \\ (... \\) (...) ve \\ (... \\) (...) olur.

Gönderinin sonunda, normal ifadenin kullanımına ilişkin bazı örnekler aşağıda verilmiştir:

$ kedi metni1 1 elma 2 armut 3 muz $ grep p metin1 1 elma 2 armut $ grep bezelye metin1 2 armut $ grep "p *" metin1 1 elma 2 armut 3 muz $ grep "pp *" metin1 1 elma 2 armut $ grep " x "metin1 $ grep" x * "metin1 1 elma 2 armut 3 muz $ kedi metni1 | grep "l \\ | n" 1 elma 3 muz $ echo -e "burada \\ n * bul" | grep "\\ *" * burada $ grep "pp \\ +" metin1 # satır bir p ve 1 veya daha fazla p içeren 1 elma $ grep "pl \\? e" metin1 1 elma 2 armut $ grep "pl \\? e" text1 # pe olası karakterle l 1 elma 2 armut $ grep "p. * r" text1 # p, r 2 armut $ grep "a .." içeren satırlarda text1 # satırında a ve ardından en az 2 karakter 1 elma 3 muz $ grep "\\ (an \\) \\ +" text1 # Daha fazla tekrar arayın bir 3 muz $ grep "an \\ (an \\) \\ +" text1 # 2 tekrar ara bir 3 muz $ grep "" text1 # search 3 veya p ile çizgiler 1 elma 2 armut 3 muz $ echo -e "burada \\ n * bir yerde \\ n bul." | grep "[. *]" * burada bir yerde. $ # 3 ile 7 arasındaki karakterleri arar $ echo -e "123 \\ n456 \\ n789 \\ n0" | grep "" 123 456 789 $ # Bir rakam arıyoruz ve ardından $ grep "[[: digit:]] [^ nr] * $" text1 1 apple $ sed -e "/ \\ (a . * a \\) \\ | \\ (p. * p \\) / s / a / A / g "text1 #, a'nın a'dan sonra geldiği tüm satırlarda a'yı A ile değiştirin veya p, p 1 Apple 2 armut 3 bAnAnA $ sed -e "/ ^ [^ lmnXYZ] * $ / s / ear / each / g" text1 # kulağı, lmnXYZ ile başlamayan her satırda değiştirin 1 elma 2 şeftali 3 muz $ echo "İlk. Bir ifade. Bu bir cümle. " | \\ # Cümledeki son kelimeyi SON DÜNYA ile değiştirin. \u003e sed -e "s / [^] * \\ ./ LAST WORD./g" İlk. SON BİR SÖZ. Bu SON SÖZCÜK.

Düzenli ifadeler, çeşitli görevler için kullanılabilen dizeleri eşleştirme, değiştirme ve değiştirme için çok güçlü bir araçtır. İşte ana olanlar:

  • Metin girişi kontrolü;
  • Bir dosyadaki metni arayın ve değiştirin;
  • Dosyaların toplu olarak yeniden adlandırılması;
  • Apache gibi hizmetlerle etkileşim;
  • Bir dizeyi bir desene göre kontrol etmek

Bu uzak tam liste, normal ifadelerle yapabileceğiniz daha pek çok şey var. Ancak onları oluşturmak için özel bir dil kullanıldığından, yeni kullanıcılar için çok karmaşık görünebilirler. Ancak sağlanan yetenekler göz önüne alındığında, Linux normal ifadeleri herkes tarafından bilinmeli ve kullanılmalıdır. sistem yöneticisi.

Bu makalede, bu aracın tüm özelliklerini anlayabilmeniz için size yeni başlayanlar için bash normal ifadeleri konusunda rehberlik edeceğiz.

Normal ifadelerde kullanılabilecek iki tür karakter vardır:

  • normal harfler;
  • meta karakterler.

Normal karakterler, herhangi bir dizeyi oluşturan harfler, sayılar ve noktalama işaretleridir. Tüm metinler harflerden oluşur ve bunları metinde istediğiniz konumu bulmak için normal ifadelerde kullanabilirsiniz.

Metakarakterler başka bir şeydir, normal ifadelere güç veren şeydir. Meta karakterlerle, tek bir karakteri aramaktan çok daha fazlasını yapabilirsiniz. Karakter kombinasyonlarını arayabilir, dinamik sayıda karakter kullanabilir ve aralıklar seçebilirsiniz. Tüm özel karakterler iki türe ayrılabilir; bunlar, sıradan karakterlerin yerine geçen yedek karakterler veya bir karakterin kaç kez tekrarlanabileceğini gösteren operatörlerdir. Normal ifade sözdizimi şöyle görünecektir:

normal_karakter özel character_operator

özel karakter özel character_operator

  • - gerçek özel karakterler ters eğik çizgi ile başlar ve ayrıca noktalama işareti şeklinde özel bir karakter kullanmanız gerektiğinde de kullanılır;
  • ^ - satırın başlangıcını gösterir;
  • $ - satırın sonunu gösterir;
  • * - önceki karakterin 0 veya daha fazla kez tekrarlanabileceğini belirtir;
  • + - önceki karakterin bir veya daha fazla kez tekrarlanması gerektiğini belirtir;
  • ? - önceki karakter sıfır veya bir kez ortaya çıkabilir;
  • (n) - önceki karakterin kaç kez (n) tekrarlanacağını gösterir;
  • (N, n) - önceki karakter N'den n'ye kadar tekrarlanabilir;
  • . - satır besleme dışında herhangi bir karakter;
  • - parantez içinde belirtilen herhangi bir karakter;
  • x | y - x sembolü veya y sembolü;
  • [^ az] - parantez içinde belirtilenler dışında herhangi bir karakter;
  • - belirtilen aralıktaki herhangi bir karakter;
  • [^ a-z] - aralıkta olmayan herhangi bir karakter;
  • b - boşluk içeren bir kelime sınırını belirtir;
  • B - karakterin bir kelimenin içinde olması gerektiği anlamına gelir, örneğin, ux, uxb veya tuxedo ile eşleşir, ancak Linux ile eşleşmez;
  • d - sembolün bir rakam olduğu anlamına gelir;
  • D - dijital olmayan karakter;
  • n - satır besleme karakteri;
  • s - boşluk, boşluk, sekme vb. karakterlerden biri;
  • S - boşluk dışında herhangi bir karakter;
  • t - tablo karakteri;
  • v - dikey sekme karakteri;
  • w - alt çizgi dahil herhangi bir alfabetik karakter;
  • W - alt çizgi dışında herhangi bir alfabetik karakter;
  • uXXX - Unicdoe sembolü.

Özel karakterin bir sonraki olduğunu belirtmek için birebir özel karakterlerden önce bir eğik çizgi kullanılması gerektiğine dikkat etmek önemlidir. Bunun tersi de doğrudur, eğer eğik çizgi olmadan kullanılan özel bir karakteri normal bir karakter olarak kullanmak istiyorsanız, bir bölü çizgisi eklemeniz gerekir.

Örneğin, metinde 1+ 2 \u003d 3 dizesini aramak istiyorsunuz. Bu dizeyi normal bir ifade olarak kullanırsanız, hiçbir şey bulamazsınız, çünkü sistem artıyı özel bir karakter olarak yorumlar, bu da önceki birimin bir veya daha fazla kez tekrarlanması gerektiğini söyler. Bu nedenle, kaçılması gerekir: 1 + 2 \u003d 3. Kaçışsız, normal ifademiz yalnızca 11 \u003d 3 veya 111 \u003d 3 dizesiyle eşleşir ve bu böyle devam eder. Eşittirden önce bir satır koymaya gerek yoktur çünkü özel bir karakter değildir.

Normal ifadeleri kullanma örnekleri

Artık temelleri ele aldığımıza ve her şeyin nasıl çalıştığını bildiğinize göre, linux grep normal ifadeleri hakkında edinilen bilgileri pratikte pekiştirmek kalır. Bir satırın başlangıcını ve sonunu belirten çok kullanışlı iki özel karakter ^ ve $ 'dır. Örneğin, sistemimize kayıtlı, adı s ile başlayan tüm kullanıcıları almak istiyoruz. Daha sonra normal ifade uygulanabilir "^ S"... Egrep komutunu kullanabilirsiniz:

egrep "^ s" / etc / passwd

Satırdaki son karaktere göre satır seçmek istersek, bunun için $ kullanabiliriz. Örneğin, hepsini seçelim sistem kullanıcıları, kabuk olmadan, bu tür kullanıcılar için girişler yanlış ile sonuçlanır:

egrep "yanlış $" / etc / passwd

S veya d ile başlayan kullanıcı adlarını yazdırmak için şu ifadeyi kullanın:

egrep "^" / etc / passwd

Aynı sonuç "|" karakteri kullanılarak da elde edilebilir. İlk seçenek, aralıklar için daha uygundur ve ikincisi daha çok normal veya / veya:

egrep "^" / etc / passwd

Şimdi adı üç karakterden fazla olan tüm kullanıcıları seçelim. Kullanıcı adı iki nokta üst üste ile biter. Kolondan önce üç kez tekrarlanması gereken herhangi bir alfabetik karakter içerebileceğini söyleyebiliriz:

egrep "^ w (3):" / etc / passwd

sonuçlar

Bu makalede Linux normal ifadelerini ele aldık, ancak bunlar sadece temel bilgilerdi. Biraz daha derine inerseniz, bu araçla yapabileceğiniz çok daha ilginç şeyler olduğunu göreceksiniz. Normal ifadeleri öğrenmek için harcanan zaman kesinlikle buna değer.

Sonuç olarak, Yandex'den normal ifadeler hakkında bir konuşma: