Ders 16 / 24
Akış Editörü ile Dönüştürme
Yerine koyma komutu ve bayrakları, geri başvurularla yeniden yazma, adres ve aralık seçimi, yerinde düzenlemenin gerçekleştirimler arasındaki uyumsuzluğu.
İçindekiler
Filtreleme satırları seçer ama değiştirmez. Kütükteki zaman damgasından yalnızca saati almak, sayısal kimlik içeren yolları tek bir kalıba indirmek ya da satırı ayrılmış bir kayda çevirmek için satırın kendisini dönüştürmek gerekir.
Akış editörü (stream editor), girdiyi satır satır okuyup her satıra bir komut dizisi uygulayan ve sonucu yazan süzgeçtir. Etkileşimli bir editörden farkı, kararların önceden verilmiş olmasıdır: dosya açılmaz, hiçbir şey görüntülenmez, akış yalnızca akar.
Yerine Koyma
En sık kullanılan komut s’dir: s/kalıp/yerine/bayraklar.
head -2 erisim.log | sed 's/HTTP\/1.1/HTTP/'
10.0.0.12 - - [07/Feb/2024:09:12:44 +0000] "GET /index.html HTTP" 200 5120 10.0.0.31 - - [07/Feb/2024:09:12:51 +0000] "GET /statik/stil.css HTTP" 200 2048
Kalıpta eğik çizgi geçtiği için kaçırılması gerekti. Ayırıcı serbesttir; s komutundan
sonra gelen ilk karakter ayırıcı sayılır:
head -1 erisim.log | sed 's|HTTP/1.1|HTTP|'
Yol içeren kalıplarda | veya # seçmek, ters bölü yığılmasını ortadan kaldırır.
Öntanımlı davranış, her satırda yalnızca ilk eşleşmeyi değiştirmektir. Bayraklar bunu değiştirir:
echo 'a-b-c-d' | sed 's/-/+/' echo 'a-b-c-d' | sed 's/-/+/g' echo 'a-b-c-d' | sed 's/-/+/3'
a+b-c-d a+b+c+d a-b-c+d
g bayrağı tüm eşleşmeleri, sayı bayrağı yalnızca N‘inci eşleşmeyi değiştirir. I
bayrağı büyük–küçük harf ayrımını kaldırır; POSIX’te tanımlı değildir ama yaygın
gerçekleştirimlerde bulunur.
Eşleşen Metni Yeniden Kullanmak
Yerine koyma bölümünde & tüm eşleşmeyi temsil eder:
head -1 erisim.log | sed -E 's/ [0-9]{3} [0-9]+$/[&]/'
10.0.0.12 - - [07/Feb/2024:09:12:44 +0000] "GET /index.html HTTP/1.1"[ 200 5120]
Gruplar \1, \2 … ile geri çağrılır. Bu, satırı istenen biçimde yeniden yazmanın
yoludur:
sed -E 's/^([0-9.]+) - - \[([^]]+)\] "([A-Z]+) ([^ ]+) [^"]*" ([0-9]{3}) ([0-9]+)$/\1|\3|\4|\5|\6/' erisim.log | head -3
10.0.0.12|GET|/index.html|200|5120 10.0.0.31|GET|/statik/stil.css|200|2048 10.0.0.12|GET|/urun/12|200|8410
Boşlukla ayrılmış ve tırnak içeren kütük satırı, boru işaretiyle ayrılmış beş alanlı bir kayda dönüştü. İkinci grup (zaman damgası) yakalandı ama kullanılmadı; yakalamak zorunludur, çünkü kalıp satırın tamamını kaplamalıdır.
Sözdizim Seçimi
sed öntanımlı olarak temel düzenli ifade sözdizimini kullanır. -E seçeneği
genişletilmiş sözdizime geçer.
Temel sözdizimde bazı işleçlerin desteği gerçekleştirime bağlıdır:
echo 'aaa' | sed 's/a\+/X/' echo 'aaa' | sed -E 's/a+/X/'
aaa X
Birinci satırda hiçbir değişiklik olmadı: bu gerçekleştirim temel sözdizimde \+
işlecini tanımıyor, kalıbı “bir a ve bir artı işareti” diye okudu ve eşleşme bulamadı.
GNU sürümünde aynı kalıp çalışır.
Sonuç: +, ?, | ve {n,m} kullanılacaksa -E yazılır. -E seçeneği hem BSD hem
GNU sürümlerinde bulunur; eski GNU betiklerinde görülen -r seçeneği ise yalnızca GNU’ya
özgüdür.
Adresler
Komutun önüne yazılan adres, komutun hangi satırlara uygulanacağını belirler.
| Adres | Anlamı |
|---|---|
5 |
beşinci satır |
$ |
son satır |
/kalıp/ |
kalıba uyan satırlar |
2,4 |
ikinci ile dördüncü satır arası |
/a/,/b/ |
a eşleşen satırdan b eşleşene kadar |
adres! |
adresin dışındaki satırlar |
d komutu satırı siler. bir, iki, uc, dort satırlarını içeren bir dosyada:
sed '2,3d' s.txt
bir dort
sed '$d' s.txt
bir iki uc
sed '/ik/d' s.txt
bir uc dort
sed '/ik/!d' s.txt
iki
! işareti seçimi tersine çevirir; son çağrı “eşleşmeyenleri sil” diyerek yalnızca
eşleşeni bıraktı.
p komutu satırı yazar. Akış editörü öntanımlı olarak her satırı zaten yazdığı için p
tek başına yineleme üretir; -n seçeneği öntanımlı yazımı kapatır ve p seçici hâle
gelir:
sed -n '2,3p' s.txt
iki uc
Bu ikili — -n ve p — filtrelemenin akış editörüyle yazılmış biçimidir. Yalnızca satır
seçmek için süzgeç aracı daha uygundur; dönüştürme ile seçim birlikte gerekiyorsa akış
editörü tek geçişte ikisini birden yapar.
Diğer Komutlar
y/abc/xyz/ karakter karşılıklarını dönüştürür; kalıp değil, birebir eşleme kullanır:
echo 'abc' | sed 'y/abc/xyz/'
xyz
q komutu, adresine ulaşıldığında akışı sonlandırır: sed '100q' ilk yüz satırı yazıp
durur ve dosyanın kalanını okumaz.
Birden çok komut -e ile ya da noktalı virgülle zincirlenir:
head -1 erisim.log | sed -e 's/HTTP\/1.1//' -e 's/ */ /g'
10.0.0.12 - - [07/Feb/2024:09:12:44 +0000] "GET /index.html " 200 5120
Komutlar her satıra sırayla uygulanır; ikinci komut, birincinin çıktısı üzerinde çalışır. Bu, bir yerine koymanın diğerini besleyebileceği anlamına gelir ve sıra değiştiğinde sonuç değişir.
Yerinde Düzenleme: Taşınabilir Değil
-i seçeneği dosyayı yerinde değiştirir. Bu seçeneğin argüman alışı iki büyük
gerçekleştirimde uyumsuzdur ve bu, kabuk betiklerindeki en yaygın taşınabilirlik
hatalarından biridir.
BSD sürümünde -i zorunlu olarak bir yedek soneki argümanı ister:
sed -i 's/bir/BIR/' s.txt
sed: 1: "s.txt ": unterminated substitute pattern
Seçenek, ardından gelen s/bir/BIR/ dizisini yedek soneki sandı ve s.txt adını komut
olarak ayrıştırmaya çalıştı. Doğru yazım boş soneki açıkça vermektir:
sed -i '' 's/bir/BIR/' s.txt
GNU sürümünde ise sone seçeneğe bitişik yazılır; ayrı bir boş argüman verilirse dosya adı sanılır:
sed -i '' 's/bir/BIR/' s.txt
sed: can't read s/bir/BIR/: No such file or directory
İki yazımdan hiçbiri her iki sürümde çalışmaz. Betiklerde -i kullanmamak, taşınabilirlik
gereken her durumda doğru karardır. Yerine, Yönlendirme dersinde kurulan desen yazılır:
sed 's/bir/BIR/' s.txt > s.yeni && mv s.yeni s.txt
Bu desen üç üstünlük taşır: her yerde aynı çalışır, sed başarısız olursa özgün dosya
bozulmaz ve mv aynı dosya sisteminde atomiktir — dosyayı okuyan başka bir süreç ya eski
ya yeni içeriği görür, yarım hâlini değil.
-i seçeneğinin kendisi de bunu yapar: geçici dosyaya yazıp yer değiştirir. Sağladığı tek
şey yazım kısalığıdır ve bedeli taşınabilirliktir.
Betiğe Uygulama
Kütükteki yolların bir bölümü sayısal kimlik içeriyor: /urun/12 ve /urun/45 ayrı ayrı
sayıldığında ikisi de listenin altında kalır. Kimlikleri tek bir simgeye indirmek, hangi
uç noktanın yoğun olduğunu görünür kılar:
kutuk=erisim.log cut -d' ' -f7 "$kutuk" | sed -E 's#/[0-9]+#/:id#g' | sort | uniq -c | sort -rn
6 /urun/:id 6 /api/veri 4 /yok.html 4 /index.html 3 /statik/stil.css 3 /panel 2 /gizli 1 /giris 1 /eski-sayfa
/urun/:id altı istekle listenin başına çıktı; ayrı sayıldığında üçer istekle dördüncü ve
beşinci sıradaydı. Normalleştirme, sayımın neyi ölçtüğünü değiştirir — bu bir biçim
düzeltmesi değil, çözümleme kararıdır ve rapor çıktısında belirtilmelidir.
İkinci uygulama, zaman damgasından saat alanını çıkarır:
sed -E 's/^.*:([0-9]{2}):[0-9]{2}:[0-9]{2} .*$/\1/' "$kutuk" | sort | uniq -c
30 09
Örnek kütüğün tamamı tek bir saat dilimine düştüğü için tek satır çıktı; günlere yayılan gerçek bir kütükte bu, yük dağılımını veren bir sütun üretir.
Kalıptaki ^.*: bölümü açgözlüdür ve son iki nokta üst üsteye kadar ilerler; sonraki
gruplar bu yüzden dakika ve saniyeyi eşler. Açgözlülüğün burada işe yaraması rastlantı
değildir, ama kalıbın doğruluğu ona bağlıdır — açgözlülüğe dayanan kalıplar kırılgandır
ve alan tabanlı bir çözüm daha güvenlidir.
Özet
- Yerine koyma
s/kalıp/yerine/bayrakbiçimindedir; ayırıcı serbesttir ve öntanımlı davranış satır başına bir eşleşmedir. &tüm eşleşmeyi,\1,\2grupları temsil eder; satırı yeniden yazmanın aracı budur.- Temel sözdizimde
\+gibi işleçlerin desteği gerçekleştirime bağlıdır;-Eher iki yaygın sürümde bulunur ve yeğlenir. - Adres komutun kapsamını belirler;
!seçimi tersine çevirir,-nilepseçici yazma sağlar. -iseçeneğinin argüman alışı BSD ve GNU sürümlerinde uyumsuzdur; taşınabilir yazım geçici dosyaya yazıp yer değiştirmektir.
Sonraki Adım
Akış editörü satırı bir metin olarak görür; alanları ancak kalıpla taklit edebilir. Kütük gibi sütunlu verilerde bu, kırılgan kalıplara yol açar. Sonraki ders alan tabanlı işlemeyi ele alır: satırı otomatik olarak alanlara bölen, alanlar üzerinde hesap yapabilen ve anahtar başına birikim tutabilen aracı — böylece önceki konuda ilişkisel dizilerle yazılan sayımlar tek satıra inecek.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.