İçeriğe geç
academia.sh

Ders 19 / 24

Kesme, Yapıştırma ve Bölme

Sütun kesme ve sınırları, dosyaları yan yana yapıştırma, karakter düzeyi dönüştürme, dosyayı parçalara bölme ve araç seçimi ölçütü.

İçindekiler

Önceki derslerin araçları satır düzeyinde çalıştı: satır seçtiler, satır dönüştürdüler, satır sıraladılar. Sütun düzeyinde kesme, iki dosyayı yan yana getirme, karakter düzeyi eşleme ve büyük bir dosyayı parçalara bölme ayrı bir araç öbeği gerektirir.

Bu ders o öbeği tanıtır ve metin işleme konusunu, hangi işin hangi araca ait olduğunu belirleyen bir ölçütle kapatır.

Sütun Kesme

cut bu kursta ilk dersten beri kullanılıyor. İki kipi vardır: alan kipi (-d ve -f) ve karakter kipi (-c).

head -2 erisim.log | cut -d' ' -f1,7,9
10.0.0.12 /index.html 200
10.0.0.31 /statik/stil.css 200
head -2 erisim.log | cut -c1-11
10.0.0.12 -
10.0.0.31 -

Karakter kipi sabit genişlikli çıktılarda — hizalanmış tablolarda, sabit alanlı kayıtlarda — kullanılır. Alan sayısının değiştiği verilerde işe yaramaz.

cut hızlıdır ve yazımı kısadır, ama üç kesin sınırı vardır.

Ayırıcı tek karakterdir.

printf 'a::b::c\n' | cut -d'::' -f2
cut: bad delimiter

Alan tabanlı araç aynı işi düzenli ifadeli ayırıcıyla yapar:

printf 'a::b::c\n' | awk -F'::' '{ print $2 }'
b

Ardışık ayırıcılar birleştirilmez. Her ayırıcı yeni bir alan başlatır:

printf 'a  b  c\n' | cut -d' ' -f2
printf 'a  b  c\n' | awk '{ print $2 }'
b

cut ikinci alanı boş buldu, çünkü iki boşluk arasında boş bir alan var. Alan tabanlı aracın öntanımlı ayırıcısı boşluk kümesi olduğu için b döndü. Hizalanmış ya da elle yazılmış metinlerde bu fark belirleyicidir.

Alan sırası değiştirilemez. İstenen alan numaraları hangi sırayla yazılırsa yazılsın, çıktı dosyadaki sırayı izler:

head -1 erisim.log | cut -d' ' -f9,1
10.0.0.12 200

Sıra değiştirmek için alan tabanlı araç gerekir:

head -1 erisim.log | awk '{ print $9, $1 }'
200 10.0.0.12

Bu üç sınır, cut için net bir kullanım alanı bırakır: tek karakterle ayrılmış, ardışık ayırıcı içermeyen ve alan sırası değişmeyecek veriler. Kütük dosyası bu tanıma uyduğu için kursun ilk konularında kullanıldı.

Yan Yana Yapıştırma

paste, dosyaların karşılıklı satırlarını birleştirir. cut işleminin tersidir.

cut -d' ' -f7 erisim.log | head -3 > y.txt
cut -d' ' -f9 erisim.log | head -3 > k.txt
paste y.txt k.txt
/index.html	200
/statik/stil.css	200
/urun/12	200

Öntanımlı ayırıcı sekmedir; -d değiştirir:

paste -d: y.txt k.txt
/index.html:200
/statik/stil.css:200
/urun/12:200

-s seçeneği her dosyanın satırlarını tek satırda birleştirir; listeyi virgülle ayrılmış metne çevirmenin kısa yoludur:

paste -sd, k.txt
200,200,200

paste, satırların konumsal olarak eşleştiğini varsayar. Bir dosyada satır eksikse tüm hizalama kayar ve sonuç sessizce yanlış olur. Anahtar üzerinden eşleştirme gerekiyorsa önceki dersteki join kullanılır; paste yalnızca sıraya güvenilebilen verilerde uygundur.

Karakter Düzeyi Dönüştürme

tr, girdideki karakterleri tek tek eşler. Kalıp tanımaz, alan tanımaz, satır tanımaz — yalnızca karakter kümeleri üzerinde çalışır ve yalnızca standart girdiden okur.

printf 'merhaba\n' | tr 'a-z' 'A-Z'
MERHABA

Üç seçenek en sık kullanılanlardır:

printf 'aaa  bbb\n' | tr -s ' '     # ardisik yinelemeleri teke indir
printf 'a1b2c3\n'   | tr -d '0-9'   # kumedeki karakterleri sil
printf 'a1b2c3\n'   | tr -cd '0-9'  # kumenin disindakileri sil
aaa bbb
abc
123

tr -s ' ' ile ardışık boşlukları teke indirmek, cut kullanılabilir hâle getirmenin yaygın bir hazırlık adımıdır.

En sık kullanımı, ayırıcıyı satır sonuna çevirerek her alanı ayrı satıra dökmektir:

tr ' ' '\n' < erisim.log | grep -c '^"GET$'
27

tr, kalıp tabanlı araçlardan çok daha ucuzdur çünkü hiçbir şey ayrıştırmaz. Karakter eşlemesi yeterliyse akış editörü çağırmaya gerek yoktur.

Dosyayı Parçalara Bölmek

split, büyük bir dosyayı sabit boyutlu ya da sabit satırlı parçalara ayırır.

mkdir -p parca
split -l 10 erisim.log parca/kutuk-
ls parca
kutuk-aa
kutuk-ab
kutuk-ac
wc -l parca/*
      10 parca/kutuk-aa
      10 parca/kutuk-ab
      10 parca/kutuk-ac
      30 total

-l N satır sayısına, -b N bayt sayısına göre böler. Sonek uzunluğu -a ile ayarlanır; öntanımlı iki harf, 676 parçaya kadar yeterlidir.

İki kullanım alanı vardır. Birincisi, bellek sınırına sığmayan bir dosyayı parça parça işlemek. İkincisi, parçaları ayrı süreçlere dağıtarak koşut işlemek — parçalar bağımsız işlenebiliyorsa toplam süre parça sayısına bölünür.

Bayt sınırına göre bölmenin satırları ortadan kesebileceğine dikkat edilmelidir; satır tabanlı veride -b yerine -l kullanılır.

Araç Seçimi

Bu konudaki altı ders, aynı veriye farklı açılardan bakan bir araç ailesi kurdu. Aralarındaki seçim ölçütü sorunun biçimidir:

Soru Araç
Hangi satırlar kalıba uyuyor süzgeç (grep)
Satırın içindeki metni değiştir akış editörü (sed)
Alanlarla hesap yap, anahtar başına birik alan tabanlı araç (awk)
Sabit ayırıcılı veriden sütun al cut
Sütunları birleştir paste, join
Karakterleri eşle, sil, sıkıştır tr
Sırala, tekilleştir, küme işlemi yap sort, uniq, comm

İki genel kural bu tablonun üzerinde durur.

En dar aracı seçin. Alan tabanlı araç, tablodaki işlerin hemen hepsini yapabilir; her şeyi onunla yazmak yine de yanlıştır. Dar araç daha kısa yazılır, daha hızlı çalışır ve okuyan kişiye niyeti anlatır. awk '/404/ { print }' yazımı, grep 404 ile aynı işi yapar ama okuyucuya “burada bir hesap var mı” diye düşündürür.

Bir problemi üç araçtan fazlasıyla çözüyorsanız aracı değiştirin. Beş halkalı boru hatları yazılabilir ve bu kursta yazıldı; ama bir betikteki her hat böyleyse, işin kabuk sınırının ötesine geçtiği düşünülmelidir. Kabuk, süreçleri birbirine bağlamakta rakipsizdir; karmaşık veri yapıları ve çok adımlı iş mantığı için tasarlanmamıştır.

Betiğe Uygulama

Metin işleme konusunun sonunda rapor.sh, üç bölümünü de asıl araçlarıyla üretiyor:

ozet() {                        # ozet KUTUK
  awk '
    { istek++; bayt += $10; sinif[substr($9, 1, 1)]++ }
    END {
      printf "istek   : %d\n", istek
      printf "bayt    : %d\n", bayt
      printf "ortalama: %.1f bayt\n", (istek ? bayt / istek : 0)
      for (s = 2; s <= 5; s++)
        printf "  %sxx %4d  %%%.1f\n", s, sinif[s], (istek ? sinif[s] * 100 / istek : 0)
    }
  ' "$1"
}

en_cok_yol() {                  # en_cok_yol KUTUK ADET
  cut -d' ' -f7 "$1" \
    | sed -E 's#/[0-9]+#/:id#g' \
    | sort | uniq -c | sort -k1,1nr -k2,2 | head -"$2"
}

hata_yollari() {                # hata_yollari KUTUK
  awk '$9 ~ /^[45]/ { n[$7]++ } END { for (y in n) printf "%3d %s\n", n[y], y }' "$1" \
    | sort -k1,1nr -k2,2
}

Her fonksiyon tek bir soruyu yanıtlıyor, tek bir veri yolu izliyor ve çıktısı belirlenimci. Betiğin iskeleti ise hâlâ eksik: hata durumunda yarım rapor üretiyor, geçici dosya bırakıyor ve elle çalıştırılmayı bekliyor.

Özet

  • cut tek karakterli ayırıcı ister, ardışık ayırıcıları birleştirmez ve alan sırasını değiştiremez; bu üç sınır dışında en ucuz sütun aracıdır.
  • paste dosyaları konumsal olarak yan yana getirir; anahtar eşleştirmesi gerekiyorsa join kullanılır.
  • tr karakter kümeleri üzerinde çalışır; kalıp tanımaz ve yalnızca standart girdiden okur.
  • split dosyayı satır ya da bayt sınırına göre parçalar; satır tabanlı veride -l kullanılır.
  • Araç seçiminde en dar araç yeğlenir; bir problem üç araçtan fazlasını gerektiriyorsa kabuk sınırının aşıldığı düşünülmelidir.

Sonraki Adım

Betik doğru çıktı üretiyor, ama yalnızca her şey yolunda gittiğinde. Bir komut başarısız olduğunda rapor yarım kalıyor ve çıkış kodu bunu bildirmiyor; tanımsız bir değişken sessizce boş dizgi olarak genişliyor. Sonraki konu bu boşlukları kapatır ve katı kip seçenekleriyle başlar: hangi hataların betiği durdurması gerektiğini, hangi seçeneğin bunu ne ölçüde sağladığını ve seçeneklerin kendi tuzaklarını ele alarak.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat