Akış Düzenleyici - Dizeler

İkame Komutu

"Bul ve değiştir" gibi metin değiştirme işlemleri herhangi bir metin düzenleyicide yaygındır. Bu bölümde, SED'nin metin değiştirmeyi nasıl gerçekleştirdiğini göstereceğiz. Aşağıda, değiştirme komutunun sözdizimi verilmiştir.

[address1[,address2]]s/pattern/replacement/[flags]

Buraya, address1 ve address2sırasıyla başlangıç ​​ve bitiş adresleridir, bunlar satır numaraları veya desen dizileri olabilir. Her iki adres de isteğe bağlı parametrelerdir. Kalıp, yerini alacak dizeyle değiştirmek istediğimiz metindir. Ek olarak, SED ile isteğe bağlı bayraklar belirleyebiliriz.

Books.txt dosyasında, her sütunu ayırmak için virgül (,) kullandık. Her bir sütunu ayırmak için dikey çubuk (|) kullanalım. Bunu yapmak için, virgül (,) yerine dikey çubuk (|) koyun.

[jerry]$ sed 's/,/ | /' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

1) A Storm of Swords | George R. R. Martin, 1216 
2) The Two Towers | J. R. R. Tolkien, 352 
3) The Alchemist | Paulo Coelho, 197 
4) The Fellowship of the Ring | J. R. R. Tolkien, 432 
5) The Pilgrimage | Paulo Coelho, 288 
6) A Game of Thrones | George R. R. Martin, 864

Dikkatlice bakarsanız, yalnızca ilk virgül değiştirilir ve ikincisi olduğu gibi kalır. Neden? Kalıp eşleşir eşleşmez, SED onu yeni dizeyle değiştirir ve sonraki satıra geçer. Varsayılan olarak, yalnızca ilk geçtiği yerin yerini alır. Tüm tekrarlamaları değiştirmek için, genel bayrağı (g) SED ile aşağıdaki gibi kullanın:

[jerry]$ sed 's/,/ | /g' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

1) A Storm of Swords | George R. R. Martin | 1216 
2) The Two Towers | J. R. R. Tolkien | 352 
3) The Alchemist | Paulo Coelho | 197 
4) The Fellowship of the Ring | J. R. R. Tolkien | 432 
5) The Pilgrimage | Paulo Coelho | 288 
6) A Game of Thrones | George R. R. Martin | 864

Artık virgüllerin (,) tüm tekrarları dikey çubukla (|) değiştirilir.

SED'ye yalnızca bir kalıp eşleşmesi başarılı olduğunda metin ikamesi yapması talimatını verebiliriz. Aşağıdaki örnek, yalnızca bir satır The Pilgrimage modelini içerdiğinde virgül (,) yerine dikey çubuk (|) koyar.

[jerry]$ sed '/The Pilgrimage/ s/,/ | /g' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

1) A Storm of Swords, George R. R. Martin, 1216 
2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage | Paulo Coelho | 288 
6) A Game of Thrones, George R. R. Martin, 864

Buna ek olarak SED, modelin belirli bir oluşumunun yerini alabilir. Virgülün (,) yalnızca ikinci örneğini dikey çubukla (|) değiştirelim.

[jerry]$ sed 's/,/ | /2' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

1) A Storm of Swords, George R. R. Martin | 1216 
2) The Two Towers, J. R. R. Tolkien | 352 
3) The Alchemist, Paulo Coelho | 197 
4) The Fellowship of the Ring, J. R. R. Tolkien | 432 
5) The Pilgrimage,Paulo Coelho | 288 
6) A Game of Thrones, George R. R. Martin  | 864

Yukarıdaki örnekte, SED komutunun sonundaki (veya bayrağın yerindeki) sayı 2. oluşumu ima etmektedir.

SED, ilginç bir özellik sağlar. Değişikliği gerçekleştirdikten sonra, SED yalnızca değiştirilen satırları gösterme seçeneği sunar. Bu amaçla SED,pyazdırmayı ifade eden bayrak. Aşağıdaki örnek yalnızca değiştirilen satırları listeler.

[jerry]$ sed -n 's/Paulo Coelho/PAULO COELHO/p' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

3) The Alchemist, PAULO COELHO, 197 
5) The Pilgrimage, PAULO COELHO, 288

Değiştirilen satırları başka bir dosyada da saklayabiliriz. Bu sonucu elde etmek için şunu kullanın:wbayrak. Aşağıdaki örnek bunun nasıl yapılacağını gösterir.

[jerry]$ sed -n 's/Paulo Coelho/PAULO COELHO/w junk.txt' books.txt

Aynı SED komutunu kullandık. İçeriğini doğrulayalımjunk.txt dosya.

[jerry]$ cat junk.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

3) The Alchemist, PAULO COELHO, 197 
5) The Pilgrimage, PAULO COELHO, 288

Büyük / küçük harfe duyarlı olmayan ikame gerçekleştirmek için, büyük / küçük harf duyarlılığını yoksay anlamına gelen i işaretini kullanın. Aşağıdaki örnek, büyük / küçük harfe duyarlı olmayan değiştirme gerçekleştirir.

[jerry]$ sed  -n 's/pAuLo CoElHo/PAULO COELHO/pi' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

3) The Alchemist, PAULO COELHO, 197 
5) The Pilgrimage, PAULO COELHO, 288

Şimdiye kadar, sınırlayıcı olarak yalnızca ön çizgi (/) karakterini kullandık, ancak sınırlayıcı olarak işaret (@), düzeltme işareti (^), ünlem işareti (!) De dikey çubuk (|) da kullanabiliriz. Aşağıdaki örnek, diğer karakterlerin sınırlayıcı olarak nasıl kullanılacağını gösterir.

Yolu değiştirmeniz gerektiğini varsayalım /bin/sed ile /home/jerry/src/sed/sed-4.2.2/sed. Dolayısıyla, SED komutunuz şuna benzer:

[jerry]$ echo "/bin/sed" | sed 's/\/bin\/sed/\/home\/jerry\/src\/sed\/sed-4.2.2\/sed/'

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

/home/jerry/src/sed/sed-4.2.2/sed

Bu komutu daha okunaklı ve anlaşılması kolay hale getirebiliriz. Dikey çubuğu (|) sınırlayıcı olarak kullanalım ve sonucu görelim.

[jerry]$ echo "/bin/sed" | sed 's|/bin/sed|/home/jerry/src/sed/sed-4.2.2/sed|'

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

/home/jerry/src/sed/sed-4.2.2/sed

Aslında! Aynı sonucu aldık ve sözdizimi daha okunaklı. Benzer şekilde, "at" işaretini (@) aşağıdaki gibi bir sınırlayıcı olarak kullanabiliriz:

[jerry]$ echo "/bin/sed" | sed 's@/bin/sed@/home/jerry/src/sed/sed-4.2.2/sed@'

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

/home/jerry/src/sed/sed-4.2.2/sed

Buna ek olarak, sınırlayıcı olarak düzeltme işareti (^) kullanabiliriz.

[jerry]$ echo "/bin/sed" | sed 's^/bin/sed^/home/jerry/src/sed/sed-4.2.2/sed^'

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

/home/jerry/src/sed/sed-4.2.2/sed

Ayırıcı olarak ünlem işaretini (!) Aşağıdaki gibi de kullanabiliriz:

[jerry]$ echo "/bin/sed" | sed 's!/bin/sed!/home/jerry/src/sed/sed-4.2.2/sed!'

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

/home/jerry/src/sed/sed-4.2.2/sed

Genel olarak, ters eğik çizgi (/) sınırlayıcı olarak kullanılır, ancak bazen SED ile desteklenen diğer sınırlayıcıları kullanmak daha uygundur.

Bir Alt Dize Oluşturma

Güçlü ikame komutunu öğrendik. Bakalım eşleşen bir metinden bir alt dize bulabilecek miyiz? Nasıl yapılacağını bir örnek yardımıyla anlayalım.

Şu metni ele alalım:

[jerry]$ echo "Three One Two"

Bunu bir sıraya göre düzenlememiz gerektiğini varsayalım. Bu, önce Bir, sonra İki ve son olarak Üç yazdırması gerektiği anlamına gelir. Aşağıdaki tek satır gerekli olanı yapar.

echo "Three One Two" | sed 's|\(\w\+\) \(\w\+\) \(\w\+\)|\2 \3 \1|'

Yukarıdaki örnekte, dikey çubuğun (|) sınırlayıcı olarak kullanıldığını unutmayın.

SED'de, alt dizeler bir gruplama operatörü kullanılarak belirtilebilir ve bunun önüne bir kaçış karakteri eklenmesi gerekir, yani, \( ve \).

\wherhangi bir harf, rakam veya alt çizgiyle eşleşen normal bir ifadedir ve "+" birden fazla karakteri eşleştirmek için kullanılır. Başka bir deyişle, normal ifade\(\w\+\) giriş dizesindeki tek kelimeyle eşleşir.

Giriş dizesinde boşlukla ayrılmış üç kelime vardır, dolayısıyla threeboşlukla ayrılmış normal ifadeler. İlk normal ifade ilk kelimeyi saklar, yani Üç, ikincisi kelimeyi saklarOneve üçüncü kelimeyi saklar Two

Bu alt dizeler tarafından anılır \N,burada N, alt dize numarasıdır. Bu nedenle\2 ikinci alt dizeyi yazdırır, yani One; \3 üçüncü alt dizeyi yazdırır, yani Two; ve \1 ilk alt dizeyi yazdırır, yani Three

Bu kelimeleri virgülle (,) ayıralım ve normal ifadeyi buna göre değiştirelim.

[jerry]$ echo "Three,One,Two" | sed 's|\(\w\+\),\(\w\+\),\(\w\+\)|\2,\3,\1|'

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

One,Two,Three

Normal ifadede artık boşluk yerine virgül (,) olduğuna dikkat edin.

Dize Değiştirme Bayrakları (yalnızca GNU SED)

Önceki bölümde, değiştirme komutunun bazı örneklerini gördük. GNU SED, değiştirme dizesinde kullanılabilen bazı özel kaçış dizileri sağlar. Bu dizge değiştirme bayraklarının GNU'ya özgü olduğunu ve diğer SED varyantlarıyla çalışmayabileceğini unutmayın. Burada dize değiştirme bayraklarını tartışacağız.

  • \ L: Yerine geçen dizede \ L belirtildiğinde, \ L'den sonraki tüm kalan karakterleri küçük harfli karakterler olarak değerlendirir. Örneğin, "ULO" karakterleri küçük harfli karakterler olarak kabul edilir.

[jerry]$ sed -n 's/Paulo/PA\LULO/p' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

3) The Alchemist, PAulo Coelho, 197
5) The Pilgrimage, PAulo Coelho, 288
  • \ u: Yerini alan dizede \ u belirtildiğinde, \ u'dan sonraki hemen karakteri büyük harf olarak değerlendirir. Aşağıdaki örnekte \ u, 'a' ve 'o' karakterlerinden önce kullanılmıştır. Bu nedenle SED, bu karakterleri büyük harf olarak ele alır.

[jerry]$ sed -n 's/Paulo/p\uaul\uo/p' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

3) The Alchemist, pAulO Coelho, 197 
5) The Pilgrimage, pAulO Coelho, 288
  • \ U: Yerine geçen dizede \ U belirtildiğinde, sözcüğün \ U'dan sonraki kalan tüm karakterlerini büyük harfli karakterler olarak değerlendirir.

[jerry]$ sed -n 's/Paulo/\Upaulo/p' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

3) The Alchemist, PAULO Coelho, 197 
5) The Pilgrimage, PAULO Coelho, 288
  • \ E: Bu bayrak \ L veya \ U ile birlikte kullanılmalıdır. \ L veya \ U bayrağıyla başlatılan dönüştürmeyi durdurur. Aşağıdaki örnekte, yalnızca ilk kelime büyük harflerle değiştirilmiştir.

[jerry]$ sed -n 's/Paulo Coelho/\Upaulo \Ecoelho/p' books.txt

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonucu alırsınız:

3) The Alchemist, PAULO coelho, 197 
5) The Pilgrimage, PAULO coelho, 288