Unix / Linux - SED ile Normal İfadeler
Bu bölümde, Unix'te SED ile düzenli ifadeler hakkında ayrıntılı olarak tartışacağız.
Normal ifade, birkaç karakter dizisini açıklamak için kullanılabilen bir dizedir. Normal ifadeler birkaç farklı Unix komutu tarafından kullanılır.ed, sed, awk, grepve daha sınırlı bir ölçüde, vi.
Buraya SED duruyor soyun editor. Bu akış odaklı düzenleyici, özellikle komut dosyalarını yürütmek için oluşturuldu. Böylece, beslediğiniz tüm girdiler geçer ve STDOUT'a gider ve girdi dosyasını değiştirmez.
Sed çağırmak
Başlamadan önce, yerel bir kopyasına sahip olduğumuzdan emin olalım. /etc/passwd çalışmak için metin dosyası sed.
Daha önce belirtildiği gibi, sed, aşağıdaki gibi bir boru yoluyla veri gönderilerek çağrılabilir -
$ cat /etc/passwd | sed
Usage: sed [OPTION]... {script-other-script} [input-file]...
-n, --quiet, --silent
suppress automatic printing of pattern space
-e script, --expression = script
...............................
cat komut içeriğini döker /etc/passwd -e sedborudan sed'in desen boşluğuna. Desen alanı, sed'in işlemleri için kullandığı dahili çalışma tamponudur.
Sed Genel Sözdizimi
Sed için genel sözdizimi aşağıdadır -
/pattern/action
Buraya, pattern normal bir ifadedir ve actionaşağıdaki tabloda verilen komutlardan biridir. Eğerpattern ihmal edildi, action yukarıda gördüğümüz gibi her satır için yapılır.
Sınırlayıcı olarak kullanıldıkları için deseni çevreleyen eğik çizgi karakteri (/) gereklidir.
Sr.No. | Aralık ve Açıklama |
---|---|
1 | p Satırı yazdırır |
2 | d Satırı siler |
3 | s/pattern1/pattern2/ Pattern1'in ilk oluşumunu pattern2 ile değiştirir |
Sed ile Tüm Satırları Silme
Şimdi sed ile tüm satırların nasıl silineceğini anlayacağız. Sed'i yeniden çağırın; ancak sed'in artık kullanması gerekiyorediting command delete line, tek harfle gösterilir d -
$ cat /etc/passwd | sed 'd'
$
Sed'e bir boru yoluyla bir dosya göndererek çağırmak yerine, aşağıdaki örnekte olduğu gibi, sed'e bir dosyadaki verileri okuması talimatı verilebilir.
Aşağıdaki komut, cat komutu olmadan önceki örnekteki ile tamamen aynı şeyi yapar -
$ sed -e 'd' /etc/passwd
$
Sed Adresleri
Sed ayrıca adresleri de destekler. Adresler ya bir dosyadaki belirli konumlardır ya da belirli bir düzenleme komutunun uygulanması gereken bir aralıktır. Sed herhangi bir adresle karşılaşmadığında, işlemlerini dosyanın her satırında gerçekleştirir.
Aşağıdaki komut, kullanmakta olduğunuz sed komutuna temel bir adres ekler -
$ cat /etc/passwd | sed '1d' |more
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$
1 rakamının, delete editkomut. Bu, sed'e, düzenleme komutunu dosyanın ilk satırında gerçekleştirmesi talimatını verir. Bu örnekte sed, ilk satırını silecektir./etc/password ve dosyanın geri kalanını yazdırın.
Sed Adres Aralıkları
Şimdi nasıl çalışacağımızı anlayacağız the sed address ranges. Peki ya bir dosyadan birden fazla satırı kaldırmak isterseniz? Sed ile aşağıdaki gibi bir adres aralığı belirtebilirsiniz -
$ cat /etc/passwd | sed '1, 5d' |more
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$
Yukarıdaki komut, 1'den 5'e kadar tüm satırlara uygulanacaktır. Bu, ilk beş satırı siler.
Aşağıdaki adres aralıklarını deneyin -
Sr.No. | Aralık ve Açıklama |
---|---|
1 | '4,10d' 4. sıradan 10. sıraya kadar olan satırlar silinir. |
2 | '10,4d' Sadece 10 inci sed eser ters yönde değil çünkü hat, silinir |
3 | '4,+5d' Bu, dosyadaki 4. satırla eşleşir, bu satırı siler, sonraki beş satırı silmeye devam eder ve ardından silme işlemini durdurur ve geri kalanını yazdırır |
4 | '2,5!d' Bu, 2. satırdan 5. satıra kadar her şeyi siler. |
5 | '1~3d' Bu, ilk satırı siler, sonraki üç satırın üzerinden geçer ve ardından dördüncü satırı siler. Sed, dosyanın sonuna kadar bu kalıbı uygulamaya devam ediyor. |
6 | '2~2d' Bu, sed'e ikinci satırı silmesini, sonraki satıra geçmesini, sonraki satırı silmesini ve dosyanın sonuna ulaşılana kadar tekrar etmesini söyler. |
7 | '4,10p' 4 itibaren hatlar th 10 kadar inci basılır |
8 | '4,d' Bu, sözdizimi hatası oluşturur |
9 | ',10d' Bu aynı zamanda sözdizimi hatası oluşturur |
Note - Kullanırken p eylem, kullanmalısınız -nsatır baskısının tekrarını önlemek için seçenek. Aşağıdaki iki komut arasındaki farkı kontrol edin -
$ cat /etc/passwd | sed -n '1,3p'
Check the above command without -n as follows −
$ cat /etc/passwd | sed '1,3p'
Değiştirme Komutu
İkame komutu ile gösterilen s, belirttiğiniz herhangi bir dizeyi, belirttiğiniz diğer dizelerle değiştirir.
Bir dizgiyi diğeriyle değiştirmek için, sed'in ilk dizenin nerede bittiği ve ikame dizesinin başladığı yer hakkında bilgiye sahip olması gerekir. Bunun için, iki dizeyi eğik çizgi (/) karakter.
Aşağıdaki komut, dizenin bir satırındaki ilk oluşumun yerini alır root ip ile amrood.
$ cat /etc/passwd | sed 's/root/amrood/'
amrood:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
..........................
Sed'in bir satırda yalnızca ilk geçtiği yeri ikame ettiğine dikkat etmek çok önemlidir. Dize kökü bir satırda birden çok kez geçerse, yalnızca ilk eşleşme değiştirilir.
Sed'in global bir ikame gerçekleştirmesi için, harfi ekleyin g aşağıdaki gibi komutun sonuna kadar -
$ cat /etc/passwd | sed 's/root/amrood/g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
...........................
İkame Bayrakları
Ek olarak aktarılabilecek bir dizi başka yararlı bayrak vardır. g bayrak ve aynı anda birden fazla belirtebilirsiniz.
Sr.No. | Bayrak ve Açıklama |
---|---|
1 | g Yalnızca ilk eşleşmeyi değil, tüm eşleşmeleri değiştirir |
2 | NUMBER Yerini sadece SAYISI inci maçın |
3 | p Değiştirme yapıldıysa, desen alanını yazdırır |
4 | w FILENAME Değiştirme yapıldıysa, sonucu FILENAME'e yazar |
5 | I or i Büyük / küçük harfe duyarlı olmayan bir şekilde eşleşir |
6 | M or m ^ Ve $ özel normal ifade karakterlerinin normal davranışına ek olarak, bu bayrak ^ 'nin yeni satırdan sonraki boş dizeyle eşleşmesine ve $ değerinin yeni satırdan önceki boş dizeyle eşleşmesine neden olur |
Alternatif Bir Dize Ayırıcı Kullanma
Eğik çizgi karakterini içeren bir dizge üzerinde bir değişiklik yapmanız gerektiğini varsayalım. Bu durumda, belirtilen karakteri girerek farklı bir ayırıcı belirtebilirsiniz.s.
$ cat /etc/passwd | sed 's:/root:/amrood:g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
Yukarıdaki örnekte kullandık : olarak delimiter eğik çizgi yerine / aramaya çalıştığımız için /root basit kök yerine.
Boş Alanla Değiştirme
Kök dizeyi listeden silmek için boş bir ikame dizesi kullanın. /etc/passwd tamamen dosya -
$ cat /etc/passwd | sed 's/root//g'
:x:0:0::/:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
Adres Değiştirme
Dizeyi değiştirmek istiyorsanız sh ip ile quiet yalnızca 10. satırda, aşağıdaki şekilde belirtebilirsiniz -
$ cat /etc/passwd | sed '10s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/quiet
Benzer şekilde, bir adres aralığı değişikliği yapmak için aşağıdaki gibi bir şey yapabilirsiniz -
$ cat /etc/passwd | sed '1,5s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/quiet
daemon:x:1:1:daemon:/usr/sbin:/bin/quiet
bin:x:2:2:bin:/bin:/bin/quiet
sys:x:3:3:sys:/dev:/bin/quiet
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
Çıktıdan da görebileceğiniz gibi, ilk beş satırda dize vardı sh olarak değiştirildi quiet, ancak satırların geri kalanı dokunulmadan kaldı.
Eşleşen Komut
Kullanacaksın p ile birlikte seçenek -n tüm eşleşen satırları aşağıdaki gibi yazdırma seçeneği -
$ cat testing | sed -n '/root/p'
root:x:0:0:root user:/root:/bin/sh
[root@ip-72-167-112-17 amrood]# vi testing
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
Normal İfadeyi Kullanma
Kalıpları eşleştirirken, daha fazla esneklik sağlayan normal ifadeyi kullanabilirsiniz.
Daemon ile başlayan tüm satırlarla eşleşen ve ardından bunları silen aşağıdaki örneği kontrol edin -
$ cat testing | sed '/^daemon/d'
root:x:0:0:root user:/root:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
Aşağıda, ile biten tüm satırları silen örnek verilmiştir. sh -
$ cat testing | sed '/sh$/d'
sync:x:4:65534:sync:/bin:/bin/sync
Aşağıdaki tablo, normal ifadelerde çok yararlı olan dört özel karakteri listelemektedir.
Sr.No. | Karakter açıklaması |
---|---|
1 | ^ Satırın başlangıcıyla eşleşir |
2 | $ Satırın sonuyla eşleşir |
3 | . Herhangi bir tek karakterle eşleşir |
4 | * Önceki karakterin sıfır veya daha fazla oluşumuyla eşleşir |
5 | [chars] Karakterlerin bir dizi karakter olduğu karakterlerde verilen karakterlerden herhangi biriyle eşleşir. Bir karakter aralığını belirtmek için - karakterini kullanabilirsiniz. |
Eşleşen Karakterler
Kullanımını göstermek için birkaç ifadeye daha bakın metacharacters. Örneğin, aşağıdaki model -
Sr.No. | İfade ve Açıklama |
---|---|
1 | /a.c/ Şunun gibi dizeler içeren satırları eşleştirir: a+c, a-c, abc, match, ve a3c |
2 | /a*c/ Aşağıdaki gibi dizelerle aynı dizelerle eşleşir: ace, yacc, ve arctic |
3 | /[tT]he/ Dizeyle eşleşir The ve the |
4 | /^$/ Boş satırlarla eşleşir |
5 | /^.*$/ Ne olursa olsun tüm bir çizgiyle eşleşir |
6 | / */ Bir veya daha fazla boşlukla eşleşir |
7 | /^$/ Maçlar blank çizgiler |
Aşağıdaki tablo, sık kullanılan bazı karakter kümelerini göstermektedir -
Sr.No. | Set ve Açıklama |
---|---|
1 | [a-z] Tek bir küçük harfle eşleşir |
2 | [A-Z] Tek bir büyük harfle eşleşir |
3 | [a-zA-Z] Tek bir harfle eşleşir |
4 | [0-9] Tek bir sayıyla eşleşir |
5 | [a-zA-Z0-9] Tek bir harf veya sayıyla eşleşir |
Karakter Sınıfı Anahtar Kelimeleri
Bazı özel anahtar kelimeler genellikle regexps, özellikle de kullanan GNU yardımcı programları regexps. Bunlar, şeyleri basitleştirdikleri ve okunabilirliği artırdıkları için sed düzenli ifadeler için çok kullanışlıdır.
Örneğin, karakterler a through z ve karakterler A through Z, anahtar kelimeye sahip böyle bir karakter sınıfı oluşturun [[:alpha:]]
Alfabe karakteri sınıfı anahtar sözcüğünü kullanarak, bu komut yalnızca /etc/syslog.conf alfabenin bir harfiyle başlayan dosya -
$ cat /etc/syslog.conf | sed -n '/^[[:alpha:]]/p'
authpriv.* /var/log/secure
mail.* -/var/log/maillog
cron.* /var/log/cron
uucp,news.crit /var/log/spooler
local7.* /var/log/boot.log
Aşağıdaki tablo, GNU sed'deki kullanılabilir karakter sınıfı anahtar sözcüklerinin tam bir listesidir.
Sr.No. | Karakter Sınıfı ve Açıklama |
---|---|
1 | [[:alnum:]] Alfasayısal [az AZ 0-9] |
2 | [[:alpha:]] Alfabetik [az AZ] |
3 | [[:blank:]] Boş karakterler (boşluklar veya sekmeler) |
4 | [[:cntrl:]] Kontrol karakterleri |
5 | [[:digit:]] Sayılar [0-9] |
6 | [[:graph:]] Görünür tüm karakterler (boşluklar hariç) |
7 | [[:lower:]] Küçük harfler [az] |
8 | [[:print:]] Yazdırılabilir karakterler (kontrol dışı karakterler) |
9 | [[:punct:]] Noktalama karakterleri |
10 | [[:space:]] Beyaz boşluk |
11 | [[:upper:]] Büyük harfler [AZ] |
12 | [[:xdigit:]] Onaltılık rakamlar [0-9 af AF] |
Aampersand Referanslama
sed metacharacter &eşleşen desenin içeriğini temsil eder. Örneğin, adında bir dosyanız olduğunu varsayalımphone.txt aşağıdaki gibi telefon numaralarıyla dolu -
5555551212
5555551213
5555551214
6665551215
6665551216
7775551217
Yapmak istiyorsun area code(ilk üç hane) daha kolay okunması için parantez içine alınır. Bunu yapmak için, "ve" yerine koyma karakterini kullanabilirsiniz -
$ sed -e 's/^[[:digit:]][[:digit:]][[:digit:]]/(&)/g' phone.txt
(555)5551212
(555)5551213
(555)5551214
(666)5551215
(666)5551216
(777)5551217
Burada desen bölümünde ilk 3 rakamı eşleştiriyorsunuz ve sonra & bu 3 haneyi çevreleyen ile değiştiriyorsunuz parentheses.
Çoklu sed Komutlarını Kullanma
Tek bir sed komutunda birden çok sed komutunu aşağıdaki gibi kullanabilirsiniz -
$ sed -e 'command1' -e 'command2' ... -e 'commandN' files
Buraya command1 vasıtasıyla commandNdaha önce tartışılan türden sed komutlarıdır. Bu komutlar, dosyalar tarafından verilen dosyalar listesindeki satırların her birine uygulanır.
Aynı mekanizmayı kullanarak yukarıdaki telefon numarası örneğini aşağıdaki gibi yazabiliriz -
$ sed -e 's/^[[:digit:]]\{3\}/(&)/g' \
-e 's/)[[:digit:]]\{3\}/&-/g' phone.txt
(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(666)555-1216
(777)555-1217
Note - Yukarıdaki örnekte, karakter sınıfı anahtar kelimesini tekrarlamak yerine [[:digit:]] üç kez değiştirdik \{3\}, bu, önceki normal ifadenin üç kez eşleştiği anlamına gelir. Ayrıca kullandık\ satır sonu vermek ve komut çalıştırılmadan önce bunun kaldırılması gerekir.
Geri Referanslar
ampersand metacharacterkullanışlıdır, ancak daha da kullanışlı olanı, normal ifadelerde belirli bölgeleri tanımlama yeteneğidir. Bu özel bölgeler, değiştirme dizelerinizde referans olarak kullanılabilir. Normal bir ifadenin belirli bölümlerini tanımlayarak, daha sonra bu bölümlere özel bir referans karakteriyle geri dönebilirsiniz.
Yapmak back references, önce bir bölge tanımlamanız ve ardından o bölgeye geri dönmeniz gerekir. Bir bölge tanımlamak içinbackslashed parenthesesilgilenilen her bölgenin çevresinde. Ters eğik çizgilerle çevrelediğiniz ilk bölge daha sonra\1, ikinci bölge \2, ve bunun gibi.
Varsayım phone.txt aşağıdaki metne sahiptir -
(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(666)555-1216
(777)555-1217
Aşağıdaki komutu deneyin -
$ cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area \
code: \1 Second: \2 Third: \3/'
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
Area code: (666) Second: 555- Third: 1215
Area code: (666) Second: 555- Third: 1216
Area code: (777) Second: 555- Third: 1217
Note - Yukarıdaki örnekte, parantez içindeki her bir normal ifadeye geri referans verilecektir. \1, \2ve bunun gibi. Kullandık\burada satır sonu vermek için. Komutu çalıştırmadan önce bu kaldırılmalıdır.