cut Komutu ile Sütun Bazlı Veri Çıkarma

Terminal’de metin işlerken en sık karşılaşılan ihtiyaçlardan biri, bir dosyadan ya da komut çıktısından belirli sütunları veya alanları ayıklamaktır. Bu iş için çoğu zaman awk ya da sed gibi güçlü araçlara başvurulur. Oysa işin sadece bir sütunu kesmek olduğu durumlarda bu araçlar biraz fazla ağır kalır. İşte tam burada cut devreye girer: sade, hızlı ve odaklı.

cut Nedir ve Ne İşe Yarar?

cut, bir metin dosyasının ya da standart girdinin her satırından belirli bölümleri kesen ve çıkaran bir Unix/Linux komutudur. 1970’lerden bu yana Unix sistemlerinde bulunur ve POSIX standardının bir parçasıdır. Yani hem Linux hem macOS hem de BSD sistemlerinde aynı şekilde çalışır.

Temel mantığı basittir: Her satırı ya karakter pozisyonuna göre, ya byte pozisyonuna göre ya da belirli bir ayırıcı karaktere göre alan numarasına göre keser. Log analizi, CSV işleme, sistem çıktılarını parse etme gibi günlük sysadmin işlerinde çok sık kullanılır.

Temel Sözdizimi

cut [SEÇENEKLER] [DOSYA]

Seçenekleri tanıyalım:

  • -b: Byte pozisyonuna göre keser
  • -c: Karakter pozisyonuna göre keser
  • -d: Alan ayırıcı karakteri belirtir (delimiter)
  • -f: Hangi alan(lar)ın kesileceğini belirtir (field)
  • –complement: Belirtilen alanlar dışındaki her şeyi getirir
  • -s: Ayırıcı karakter içermeyen satırları atlar
  • –output-delimiter: Çıktıda kullanılacak ayırıcı karakteri belirtir

En çok kullanılan kombinasyon -d ve -f ikilisidir. Şimdi bunları örneklerle görelim.

Alan Bazlı Kesme: -d ve -f Seçenekleri

Günlük işlerde en sık kullanılan senaryo, belirli bir ayırıcıyla ayrılmış alanları çekmektir. Klasik örnek olarak /etc/passwd dosyasını inceleyelim:

# /etc/passwd dosyasından sadece kullanıcı adlarını çek (1. alan)
cut -d: -f1 /etc/passwd

Çıktı şöyle görünür:

root
daemon
bin
sys
sync
games
...

Burada -d: ile ayırıcının iki nokta olduğunu söyledik, -f1 ile de sadece birinci alanı istedik. Şimdi birden fazla alan çekelim:

# Kullanıcı adı (1. alan) ve home dizini (6. alan)
cut -d: -f1,6 /etc/passwd

Alan aralığı belirtmek için tire kullanılır:

# 1'den 3'e kadar olan alanları getir (kullanıcı adı, uid, gid)
cut -d: -f1-3 /etc/passwd

Belirli bir alandan dosyanın sonuna kadar getirmek için:

# 6. alandan itibaren her şeyi getir
cut -d: -f6- /etc/passwd

Gerçek Dünya Senaryosu: CSV Dosyası İşleme

Diyelim ki sunucunuzda bir uygulama her gün kullanıcı verilerini CSV formatında bir dosyaya yazıyor. Bu dosyadan sadece belirli sütunları çekmeniz gerekiyor.

id,username,email,department,salary,start_date
1,ahmet.yilmaz,[email protected],IT,8500,2021-03-15
2,fatma.kaya,[email protected],HR,7200,2020-08-01
3,mehmet.celik,[email protected],IT,9100,2019-11-20
4,ayse.demir,[email protected],Finance,8800,2022-01-10

Sadece kullanıcı adı ve departman bilgisini çekmek için:

# Başlık satırını atlayarak kullanıcı adı ve departman bilgisini getir
tail -n +2 calisanlar.csv | cut -d, -f2,4

Çıktı:

ahmet.yilmaz,IT
fatma.kaya,HR
mehmet.celik,IT
ayse.demir,Finance

IT departmanındaki çalışanları listeleyelim ve maaşlarını görelim:

# IT departmanındakiler için username ve salary
grep ",IT," calisanlar.csv | cut -d, -f2,5

Karakter Bazlı Kesme: -c Seçeneği

Bazen veriler sabit genişlikte sütunlar halinde gelir. Eski mainframe sistemlerinden gelen loglar, bazı eski uygulama çıktıları ya da belirli formatlarda oluşturulmuş raporlar bu şekilde olabilir. Bunun için -c seçeneğini kullanırız.

# Her satırın ilk 10 karakterini getir
cut -c1-10 rapor.txt

# 5. karakterden itibaren her şeyi getir
cut -c5- dosya.txt

# Sadece 3., 7. ve 11. karakterleri getir
cut -c3,7,11 dosya.txt

Pratik bir örnek olarak, date komutunun çıktısından sadece yıl bilgisini çekelim:

# Tarih formatı: "Sat Jan 15 14:30:00 UTC 2024"
date | cut -d' ' -f6

# Ya da karakter bazlı (yıl her zaman sondan 4 karakter değilse):
date +%Y-%m-%d | cut -c1-4

Log Analizi Senaryosu

Sistem yöneticilerinin en sık yaptığı işlerden biri log analizi. Apache/Nginx access loglarını düşünelim. Tipik bir access log satırı şöyle görünür:

192.168.1.105 - ahmed [15/Jan/2024:14:30:00 +0300] "GET /api/users HTTP/1.1" 200 1542

Sadece IP adreslerini çekmek için:

# IP adreslerini çek ve benzersiz olanları say
cut -d' ' -f1 /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

HTTP durum kodlarını analiz etmek için:

# Durum kodlarını (9. alan) çek ve dağılımını gör
cut -d' ' -f9 /var/log/nginx/access.log | sort | uniq -c | sort -rn

Bu komut ile hangi HTTP status code’ların ne kadar döndüğünü hızlıca görebilirsiniz. 500 hatalarının sayısını anında tespit edebilmek, bir olay sırasında paha biçilmezdir.

İstek yapılan URL’leri toplamak için:

# 7. alan URL yolunu içerir
cut -d' ' -f7 /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

–complement Seçeneği: Tersine Kesme

Bazen istediğimiz alanları belirtmek yerine istemediğimiz alanları belirtmek daha kolay olur. --complement seçeneği tam olarak bunu yapar: Belirttiğiniz alanlar dışındaki her şeyi getirir.

Örneğin 5 sütunlu bir CSV’de 3. sütunu (hassas veri içeren şifre sütunu gibi) hariç tutmak istiyorsunuz:

# 3. sütun hariç her şeyi getir
cut -d, -f3 --complement kullanicilar.csv

# Alternatif yazım (GNU cut ile)
cut --complement -d, -f3 kullanicilar.csv

–output-delimiter ile Çıktı Formatını Değiştirme

Girdi ayırıcısı ile çıktı ayırıcısının farklı olmasını isteyebilirsiniz. Örneğin virgülle ayrılmış bir CSV’yi sekmeli (TSV) formata dönüştürmek ya da tersini yapmak yaygın bir ihtiyaçtır.

# CSV'yi pipe-separated formata dönüştür
cut -d, -f1,2,3 veri.csv --output-delimiter='|'

# Sonucu dosyaya kaydet
cut -d, -f1,2,4 calisanlar.csv --output-delimiter=$'t' > calisanlar.tsv

Daha pratik bir senaryo: /etc/passwd çıktısını daha okunabilir hale getirmek:

# Kullanıcı adı ve shell bilgisini tab ile ayırarak göster
cut -d: -f1,7 /etc/passwd --output-delimiter=$'t'

-s Seçeneği: Ayırıcısız Satırları Atla

Heterojen log dosyalarında bazı satırlar belirttiğiniz ayırıcıyı içermeyebilir. Bu durumda -s seçeneği işe yarar:

# Ayırıcı karakter içermeyen satırları atla
cut -d: -f1 -s karisik_dosya.txt

Bu özellikle boş satırlar ya da yorum satırları içeren konfigürasyon dosyalarını işlerken faydalıdır.

Pipe ile Güçlü Kombinasyonlar

cut komutunun asıl gücü diğer komutlarla birleştirildiğinde ortaya çıkar. Birkaç gerçekçi senaryo görelim.

Senaryo 1: Disk Kullanımı Raporu

# df çıktısından kullanım yüzdelerini çek ve yüksekten düşüğe sırala
df -h | tail -n +2 | tr -s ' ' | cut -d' ' -f5 | sort -rn

Daha detaylı bir rapor için:

# Bağlama noktası ve kullanım yüzdesini göster
df -h | tail -n +2 | tr -s ' ' | cut -d' ' -f5,6 | sort -t'%' -k1 -rn

Senaryo 2: Aktif Kullanıcıları Listeleme

# who komutundan kullanıcı adlarını çek, benzersiz olanları listele
who | cut -d' ' -f1 | sort -u

Senaryo 3: Ağ Bağlantılarından IP Analizi

# ss veya netstat çıktısından remote IP'leri çek
ss -tn state established | tail -n +2 | tr -s ' ' | cut -d' ' -f5 | cut -d: -f1 | sort | uniq -c | sort -rn

Senaryo 4: Cron Job Listesi

# Crontab'dan sadece komutları çek (6. alandan itibaren her şey)
crontab -l | grep -v '^#' | grep -v '^$' | cut -d' ' -f6-

Otomatik Rapor Scripti

Yukarıdaki bilgileri birleştirerek pratik bir monitoring scripti yazalım:

#!/bin/bash
# Gunluk sistem raporu - cut ile ozet bilgi toplama

echo "=== SISTEM OZET RAPORU ==="
echo "Tarih: $(date '+%Y-%m-%d %H:%M')"
echo ""

echo "--- Aktif Kullanicilar ---"
who | cut -d' ' -f1 | sort -u

echo ""
echo "--- Yuksek Disk Kullanimi (>80%) ---"
df -h | tail -n +2 | tr -s ' ' | while IFS=' ' read -r fs size used avail use mount; do
    pct=$(echo $use | cut -d'%' -f1)
    if [ "$pct" -gt 80 ] 2>/dev/null; then
        echo "$mount: %$pct kullaniliyor"
    fi
done

echo ""
echo "--- Son 10 Basarisiz SSH Girisi ---"
grep "Failed password" /var/log/auth.log 2>/dev/null | 
    tail -10 | 
    cut -d' ' -f1,2,3,11 | 
    while read line; do echo "  $line"; done

echo ""
echo "--- En Cok Istek Yapan 5 IP (Nginx) ---"
if [ -f /var/log/nginx/access.log ]; then
    cut -d' ' -f1 /var/log/nginx/access.log | 
        sort | uniq -c | sort -rn | head -5
fi

Bu scripti /etc/cron.daily/ altına koyarak her gün otomatik çalıştırabilirsiniz.

cut ile awk Karşılaştırması: Ne Zaman Hangisini Kullan?

Bu soruyu çok sık alırım. cut ve awk arasında seçim yaparken şu kriterlere bakın:

cut kullanın eğer:

  • Sadece belirli sütunları çekmeniz gerekiyorsa
  • Veri formatı düzenli ve ayırıcı karakteri sabitse
  • Hız kritikse (cut, awk’tan belirgin şekilde daha hızlıdır)
  • İşlem basitse ve transformasyon gerekmiyorsa

awk kullanın eğer:

  • Koşullu filtreleme yapmanız gerekiyorsa
  • Matematiksel işlem yapacaksanız
  • Birden fazla ayırıcıyla veya değişken genişlikteki boşluklarla çalışıyorsanız
  • Alanlar arasında hesaplama yapmanız gerekiyorsa

Örneğin çok büyük log dosyalarında (gigabyte seviyesi) sadece bir sütun çekmek için cut çok daha hızlı çalışır. 10 GB’lık bir dosyada awk '{print $1}' ile cut -d' ' -f1 arasındaki fark ölçülebilir düzeyde olabilir.

Yaygın Hatalar ve Çözümleri

Sorun: Boşlukla ayrılmış veride birden fazla ardışık boşluk olduğunda cut yanlış sonuç verir.

# Yanlis: Birden fazla boslukta beklenmeyen sonuc verir
echo "ali     20" | cut -d' ' -f2
# Cikti: bos (aradaki bosluklar ayri alan sayilir)

# Dogru: Once boslukları tek bosluga indir
echo "ali     20" | tr -s ' ' | cut -d' ' -f2
# Cikti: 20

Sorun: Alan sayısını bilmediğinizde son alanı çekmek.

# Son alani cekmenin pratik yolu
echo "a:b:c:d:e" | rev | cut -d: -f1 | rev
# Cikti: e

Sorun: Sekme karakterini ayırıcı olarak kullanmak.

# Tab ayirici icin $'t' kullan
cut -d$'t' -f2 sekme_ayirici_dosya.tsv

# Ya da dogrudan tab karakteri gir (Ctrl+V Tab)
cut -d'	' -f2 dosya.tsv

Byte Bazlı Kesme: -b Seçeneği

-b seçeneği çok nadir kullanılır ama binary dosyaları ya da multibyte karakter setlerini işlerken kritik olabilir. -c ile -b arasındaki fark, çok baytlı karakterlerde (UTF-8 gibi) ortaya çıkar. -c karakter sayar, -b byte sayar.

# İlk 5 byte
cut -b1-5 dosya.txt

# Türkçe karakterler içeren bir dosyada fark gözlemlemek için
echo "çalışma" | cut -c1-3   # İlk 3 karakter: çal
echo "çalışma" | cut -b1-3   # İlk 3 byte: ç (2 byte) + a = "ça"

Günlük kullanımda genellikle -c tercih edilir çünkü karakterleri doğru şekilde sayar.

Sonuç

cut komutu, görünürde basit ama pratikte vazgeçilmez bir araçtır. Özellikle log analizi, CSV işleme ve sistem bilgilerini parse etme gibi tekrarlayan sysadmin görevlerinde awk ya da sed gibi ağır silahları çekmeden işi halledebilmek büyük avantaj sağlar.

Komutun gücü biraz da felsefesinden gelir: Tek bir şeyi iyi yapar. Unix felsefesinin tam anlamıyla bir örneği olan cut, diğer araçlarla pipe üzerinden birleştirildiğinde gerçek değerini gösterir. sort, uniq, grep, tr ve wc ile kombinlandığında çok karmaşık metin işleme pipelines’ları kurabilirsiniz.

Günlük iş akışınıza cutı dahil etmenin en iyi yolu, bir dahaki log analizinde ya da veri çekme işleminde refleks olarak denemektir. Büyük ihtimalle ihtiyacınızı karşılayacak ve sizi daha karmaşık bir çözüm yazmaktan kurtaracaktır.

Yorum yapın