sort ve uniq Komutları ile Veri Sıralama ve Tekilleştirme

Günlük sistem yönetimi işlerinde log dosyalarına bakmak, kullanıcı listelerini temizlemek ya da büyük veri setlerinden anlamlı bilgi çıkarmak zorunda kalıyorsunuz. İşte tam bu noktada sort ve uniq ikilisi devreye giriyor. Bu iki komut, terminal dünyasının en sade ama bir o kadar da güçlü araçlarından. Birlikte kullanıldıklarında veri temizleme, analiz ve raporlama işlerini inanılmaz derecede hızlandırıyorlar. Bu yazıda bu iki komutu derinlemesine inceleyeceğiz, gerçek dünya senaryolarıyla pekiştireceğiz.

sort Komutu: Verileri Düzenlemek

sort, adından da anlaşılacağı gibi, girdi olarak aldığı satırları belirli bir kritere göre sıralar. Varsayılan davranışı alfabetik sıralamadır, ancak parametrelerle çok daha fazlasını yapabilirsiniz.

Temel Kullanım

En basit haliyle bir dosyayı sıralamak:

sort kullanicilar.txt

Bu komut, kullanicilar.txt dosyasının içeriğini alfabetik olarak sıralayıp ekrana basar. Orijinal dosyayı değiştirmez. Eğer sonucu kaydetmek istiyorsanız:

sort kullanicilar.txt -o sirali_kullanicilar.txt

ya da klasik yöntemle:

sort kullanicilar.txt > sirali_kullanicilar.txt

sort Parametreleri

  • -r: Ters sıralama (Z’den A’ya veya büyükten küçüğe)
  • -n: Sayısal sıralama yapar. Yoksa “10” değeri “2”den önce gelir çünkü karakter karşılaştırması yapılır
  • -h: İnsan tarafından okunabilir sayıları sıralar (1K, 5M, 2G gibi)
  • -k: Belirli bir sütuna göre sıralama yapar
  • -t: Alan ayracını belirler
  • -u: Tekrar eden satırları kaldırır (uniq gibi davranır)
  • -f: Büyük/küçük harf farkını yok sayar
  • -b: Baştaki boşlukları yok sayar
  • -R: Rastgele sıralama yapar
  • -o: Çıktıyı dosyaya yazar

Sayısal Sıralama Neden Önemli?

Bunu bir örnekle görelim. Bir dosyada şu değerler olsun: 2, 10, 1, 20, 3.

echo -e "2n10n1n20n3" | sort
# Çıktı: 1, 10, 2, 20, 3 (alfabetik, yanlış!)

echo -e "2n10n1n20n3" | sort -n
# Çıktı: 1, 2, 3, 10, 20 (sayısal, doğru!)

Alfabetik sıralamada “10”, “2”den önce gelir çünkü “1” karakteri “2”den küçüktür. Log dosyalarında port numaraları, dosya boyutları veya PID’lerle çalışırken -n parametresini unutmamak kritik.

Belirli Sütuna Göre Sıralama

Sistem yöneticiliğinde sık sık sütunlu veriyle karşılaşırsınız. /etc/passwd dosyasını UID’ye göre sıralamak istediniz diyelim:

sort -t: -k3 -n /etc/passwd

Burada -t: iki nokta üst üsteyi ayraç olarak tanımlıyor, -k3 üçüncü sütunu seçiyor ve -n sayısal sıralama yapıyor. Bu sayede sistemizdeki kullanıcıları UID sırasına göre görebiliyorsunuz.

Çoklu sütunla sıralama da mümkün:

sort -t: -k1,1 -k3,3n /etc/passwd

Bu komut önce kullanıcı adına göre, eşitlik durumunda UID’ye göre sıralar.

uniq Komutu: Tekrarları Elemek

uniq, komşu yani bitişik tekrarlayan satırları tespit eder ve işler. Burası kritik bir nokta: uniq sadece ardışık tekrarlayan satırları tanır. Bu yüzden neredeyse her zaman sort ile birlikte kullanılır.

Temel Kullanım

uniq tekrarli_veri.txt

Eğer dosyada şunlar varsa:

elma
elma
armut
elma

uniq sadece ilk iki “elma”yı birleştirir, üçüncü “elma” farklı bir yerde olduğu için ayrı kalır. Doğru kullanım için önce sıralayın:

sort tekrarli_veri.txt | uniq

uniq Parametreleri

  • -c: Her satırın kaç kez tekrarlandığını sayar ve başına yazar
  • -d: Sadece tekrarlanan satırları gösterir
  • -u: Sadece tekrarlanmayan (benzersiz) satırları gösterir
  • -i: Büyük/küçük harf farkını yok sayar
  • -f N: İlk N alanı atlar, geriye kalanla karşılaştırır
  • -s N: İlk N karakteri atlayarak karşılaştırır
  • -w N: Karşılaştırmayı sadece ilk N karakterle sınırlar

Tekrar Sayısını Görmek

-c parametresi log analizi için paha biçilemez:

sort access.log | uniq -c

Bu çıktı şöyle görünür:

    142 192.168.1.10
      3 192.168.1.11
     89 10.0.0.5

Hangi IP’nin kaç kez bağlandığını tek satırda görebiliyorsunuz.

Gerçek Dünya Senaryoları

Senaryo 1: Web Sunucusu Log Analizi

Bir web sunucusunda anormal trafik var şüphesi var. Apache ya da Nginx access loglarından en çok istek yapan IP adreslerini bulmak istiyorsunuz:

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

Bu komut zincirini açıklayalım:

  • awk '{print $1}' her satırdan IP adresini (ilk alan) alır
  • sort IP’leri alfabetik sıraya koyar (uniq için gerekli)
  • uniq -c her IP’nin kaç kez geçtiğini sayar
  • sort -rn sayıya göre büyükten küçüğe sıralar
  • head -20 en üstteki 20 sonucu gösterir

Çıktıda bir IP’nin binlerce istek attığını görüyorsanız muhtemelen bir bot ya da DDoS girişimiyle karşı karşıyasınızdır.

Senaryo 2: Sistem Kullanıcı Denetimi

Birden fazla sunucudan kullanıcı listesi topladınız ve hangi kullanıcıların tüm sunucularda ortak olduğunu, hangilerinin sadece tek sunucuda tanımlı olduğunu öğrenmek istiyorsunuz:

# Tüm sunuculardaki kullanıcıları tek dosyaya toplayın
cat sunucu1_kullanicilar.txt sunucu2_kullanicilar.txt sunucu3_kullanicilar.txt | sort | uniq -c | sort -rn

Burada sayısı 3 olan kullanıcılar üç sunucuda da var. Sayısı 1 olan kullanıcılar ise sadece bir sunucuda tanımlı, bu bir güvenlik açığı olabilir ya da kasıtlı bir yapılandırma olabilir, kontrol etmek gerekir.

Sadece tekrarlanmayan kullanıcıları görmek için:

cat sunucu1_kullanicilar.txt sunucu2_kullanicilar.txt | sort | uniq -u

Senaryo 3: Disk Kullanım Analizi

du komutuyla büyük dizinleri bulup sıralamak:

du -sh /var/* 2>/dev/null | sort -h -r | head -10

-h parametresi sort‘a “human readable” değerleri anlayacağını söylüyor. Böylece “1G”, “500M”, “2K” gibi değerleri doğru sıraya koyabiliyor. Bu komut /var altındaki en büyük 10 dizini gösterir. Disk dolmaya başladığında ilk çalıştırdığım komutlardan biridir.

Senaryo 4: SSH Brute Force Tespiti

Auth loglarından başarısız SSH denemelerini analiz etmek:

grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -15

Bu komut başarısız oturum açma denemelerinde kullanılan kaynak IP adreslerini sayar ve en çok deneme yapandan başlayarak listeler. Sonuçta 100’ün üzerinde deneme yapan bir IP varsa fail2ban ya da iptables kurallarıyla engellemek gerekir.

Senaryo 5: Paket Listesi Karşılaştırma

İki sunucunun paket listesini karşılaştırmak istiyorsunuz, belki bir production ve staging sunucu arasındaki farkları bulmak için:

# Sunucu 1'de
dpkg --get-selections | awk '{print $1}' | sort > /tmp/sunucu1_paketler.txt

# Sunucu 2'de aynısını yapın ve dosyayı kopyalayın
# Sonra karşılaştırın
comm -23 sunucu1_paketler.txt sunucu2_paketler.txt

comm komutu iki sıralı dosyayı karşılaştırır. -23 seçeneği sadece birinci dosyada olan, ikincisinde olmayan satırları gösterir. Bu sayede hangi paketlerin eksik olduğunu hızla bulabilirsiniz.

Alternatif olarak uniq ile de yapılabilir:

cat sunucu1_paketler.txt sunucu2_paketler.txt | sort | uniq -u

Bu yaklaşım her iki dosyada da tekrarlanmayan yani sadece birinde olan paketleri gösterir.

İleri Düzey Kullanım Örnekleri

Çoklu Alan Sıralaması

CSV benzeri bir dosyada önce departmana sonra maaşa göre sıralamak:

sort -t',' -k2,2 -k3,3rn calisanlar.csv

Bu komut önce ikinci sütuna (departman) göre alfabetik, sonra üçüncü sütuna (maaş) göre büyükten küçüğe sıralar. Aynı departmandaki en yüksek maaşlı çalışan başa gelir.

Büyük Dosyalarda Bellek Optimizasyonu

Gigabyte’larca log dosyasını sıralarken bellek sıkıntısı yaşanabilir. sort‘un -S parametresiyle bellek limitini ayarlayabilirsiniz:

sort -S 2G buyuk_log_dosyasi.log | uniq -c | sort -rn > analiz_sonucu.txt

-T parametresiyle geçici dosyaların yazılacağı dizini de belirtebilirsiniz:

sort -T /data/tmp -S 4G cok_buyuk_dosya.log > sirali_cikti.log

Rastgele Örnekleme

Büyük bir veri setinden rastgele örneklem almak için:

sort -R buyuk_veri.txt | head -1000 > ornek_veri.txt

Bu, özellikle test senaryoları için kullanışlı. Gerçek prodüksiyon verisinden temsili bir sample almak istediğinizde işe yarıyor.

Tarihe Göre Log Sıralama

Özel format içeren log dosyalarını sıralarken dikkatli olmak gerekir. ISO format tarihler (YYYY-MM-DD) zaten alfabetik sıralamayla doğru çalışır:

grep "ERROR" /var/log/uygulama.log | sort -k1,2 | uniq

Ama Amerikan formatı tarih (MM/DD/YYYY) varsa işler karmaşıklaşır, awk ile önce formatı dönüştürmek gerekebilir.

Duplicate Satırları Ayırt Etmek

Bazen tekrarlanan kayıtları bulmak ve ayrı bir dosyaya kaydetmek istersiniz:

sort veri.txt | uniq -d > tekrar_edenler.txt
sort veri.txt | uniq -u > tekrar_etmeyenler.txt

Bu yaklaşım veri temizleme süreçlerinde çok işe yarar. Örneğin bir müşteri listesinde duplicate kayıtları bu şekilde ayırabilirsiniz.

Pipe ile Güçlü Kombinasyonlar

sort ve uniq‘in gücü asıl pipe ile diğer komutlarla birleştirildiğinde ortaya çıkıyor.

En Sık Kullanılan Komutlar

Bash history’nizden en sık kullandığınız komutları bulmak:

history | awk '{print $2}' | sort | uniq -c | sort -rn | head -10

Bu komutun çıktısı hem nostaljik hem de öğretici. Hangi komutlara en çok başvurduğunuzu görürsünüz.

Açık Port Özeti

Sistemdeki açık portları düzenli şekilde listelemek:

ss -tuln | awk 'NR>1 {print $1, $5}' | sort -k2 -t' ' | uniq

Cron Job Analizi

Tüm kullanıcıların cron job’larını toplayıp tekrarları elemek:

for user in $(cut -f1 -d: /etc/passwd); do
    crontab -u $user -l 2>/dev/null
done | grep -v "^#" | grep -v "^$" | sort | uniq

Bu script, sistemdeki tüm aktif cron job’ları duplicate olmadan listeler. Güvenlik denetimlerinde çok faydalı.

Performans İpuçları

sort CPU ve RAM yoğun bir işlemdir. Büyük dosyalarla çalışırken şunlara dikkat edin:

  • Mümkünse önce grep veya awk ile veriyi küçültün, sonra sıralayın
  • sort --parallel=4 ile işlemci çekirdeklerini daha iyi kullanabilirsiniz
  • Çok büyük dosyalarda /tmp yerine ayrı bir disk bölümüne yönlendirin çünkü sort geçici dosyalar oluşturur
  • -u ile sort‘u kullanmak bazen sort | uniq‘den daha hızlıdır çünkü tek geçişte işi bitirir

Paralel sıralama örneği:

sort --parallel=8 -S 4G cok_buyuk_dosya.log -o sirali_cikti.log

Bu komut 8 çekirdek kullanır ve 4GB bellek ayırır. Çok büyük dosyalarda ciddi hız farkı yaratır.

Sık Yapılan Hatalar

uniq’i sort’suz kullanmak: En yaygın hata. uniq sadece ardışık satırları karşılaştırır, önceden sıralamamışsanız beklediğiniz sonucu almıyorsunuz.

Sayısal değerleri alfabetik sıralamak: -n parametresini unutmak. Özellikle port numaraları, PID’ler veya dosya boyutlarında yanıltıcı sonuçlar çıkar.

Büyük/küçük harf tutarsızlığı: Email adresleri ya da kullanıcı adları gibi verilerde “Admin” ve “admin” farklı satırlar olarak işlenir. -f parametresini kullanmayı unutmayın.

Encoding sorunları: Türkçe karakter içeren dosyalarda sıralama bazen beklenmedik davranır. LC_ALL=C sort ya da LC_ALL=tr_TR.UTF-8 sort ile locale’i açıkça belirtmek bu sorunu çözer:

LC_ALL=C sort turkce_dosya.txt | uniq

Sonuç

sort ve uniq, Linux sistem yöneticisinin en temel silahlarından ikisi. Bu iki komut tek başlarına sade görünse de birleştirildiğinde ve diğer araçlarla pipe’landığında çok güçlü veri analiz süreçleri oluşturabilirsiniz. Log analizi, kullanıcı yönetimi, güvenlik denetimi, disk yönetimi gibi günlük işlerin büyük bölümü bu iki komutla ya da bunları içeren pipe zincirleriyle çözülebilir.

Özellikle şunu vurgulamak isterim: Karmaşık bir problemi çözmek için hep karmaşık araçlara ihtiyaç duymazsınız. Bazen tek ihtiyacınız sort | uniq -c | sort -rn | head gibi bir zincir oluyor. Bu basitlik, Unix felsefesinin en güzel yansımalarından biri.

Komutları ezberlemekten öte, ne zaman hangi parametreyi kullanacağınızı anlamak önemli. Pratiğin en iyi öğretici olduğunu unutmayın, kendi log dosyalarınızla, kendi verilerinizle denemeler yapın. Her sistemin kendine özgü sorunları ve veri yapıları var, ama bu komutların esnekliği neredeyse her durumda bir çözüm üretmenize olanak sağlıyor.

Yorum yapın