nl Komutu ile Satır Numaralandırma ve Çıktı Biçimlendirme

Terminal’de metin dosyalarıyla çalışırken satır numarası eklemek, log analizi yaparken referans noktası oluşturmak ya da çıktıyı belirli bir formatta sunmak istediğinde nl komutu seni şaşırtacak kadar kullanışlı bir araç olduğunu kanıtlar. Çoğu sysadmin cat -n ile geçiştirir bu işi, ama nl tam olarak bu iş için tasarlanmış, çok daha esnek ve kontrol edilebilir bir araçtır. Bu yazıda nl komutunu her köşesiyle inceleyeceğiz, gerçek dünya senaryolarıyla nasıl kullanacağını göstereceğiz.

nl Komutu Nedir ve Neden Kullanılır?

nl (number lines), bir dosyanın ya da standart girdinin satırlarına numara ekleyerek çıktı veren bir Unix/Linux aracıdır. İlk bakışta basit gibi görünse de, hangi satırların numaralandırılacağını, numaraların nasıl biçimlendirileceğini, sıfırlama davranışını ve hatta mantıksal sayfa bölümlerini kontrol etmeni sağlayan güçlü seçenekler sunar.

cat -n ile karşılaştırıldığında nl‘nin farkı şudur: cat -n tüm satırları körü körüne numaralandırır. Boş satırlar dahil her şey sayılır. nl ise varsayılan olarak boş satırları atlar, sadece içerik barındıran satırları numaralandırır. Üstelik mantıksal bölümler (header, body, footer) kavramını anlayan tek komuttur.

Hangi senaryolarda ihtiyaç duyarsın?

  • Büyük config dosyalarında belirli satır numaralarına referans vermek istediğinde
  • Log dosyalarını analiz ederken “kaçıncı satırda ne var” sorusuna cevap ararken
  • Script çıktılarını formatlamak ve okunabilir raporlar üretmek istediğinde
  • Kod dosyalarını satır numarasıyla birlikte paylaşmak ya da incelemek gerektiğinde
  • Pipe zincirlerinde diğer komutlarla birleştirerek filtrelenmiş çıktıları numaralandırmak istediğinde

Temel Kullanım

En yalın haliyle nl bir dosya adı alır ve satır numarasıyla birlikte çıktı verir.

nl /etc/ssh/sshd_config

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

     1	Port 22
     2	#AddressFamily any
     3	#ListenAddress 0.0.0.0
     4	ListenAddress ::

Varsayılan davranışta satır numaraları sağa hizalanmış 6 karakter genişliğindedir ve bir tab karakteriyle içerikten ayrılır. Boş satırlar numaralandırılmaz ama çıktıda yine de görünür.

Standart girdiyle de çalışabilirsin, pipe zincirlerinde bu çok işe yarar:

grep "error" /var/log/syslog | nl

Bu komut, syslog’dan sadece “error” içeren satırları çeker ve onları sırayla numaralandırır. Kaç tane hata satırı olduğunu görmek için en alttaki numaraya bakman yeterli.

Temel Parametreler

nl komutunun parametrelerini iyi bilmek, onu gerçekten güçlü bir araca dönüştürür.

-b (body numbering style): Gövde satırlarının nasıl numaralandırılacağını belirler. En kritik parametredir.

  • -b a: Tüm satırları numaralandırır, boş olanlar dahil
  • -b t: Sadece boş olmayan satırları numaralandırır (varsayılan)
  • -b n: Hiçbir satırı numaralandırmaz
  • -b p’regex’: Belirtilen düzenli ifadeyle eşleşen satırları numaralandırır

-h (header numbering style): Header bölümü için numaralandırma stili, aynı -b seçeneklerini alır.

-f (footer numbering style): Footer bölümü için numaralandırma stili.

-v (start number): Numaralandırmaya hangi sayıdan başlayacağını belirtir. Varsayılan 1’dir.

-i (increment): Her satırda kaçar kaçar artırılacağını belirler. Varsayılan 1’dir.

-n (number format): Numaraların nasıl formatlanacağını belirler.

  • -n ln: Sol hizalı
  • -n rn: Sağ hizalı, sıfır yok (varsayılan)
  • -n rz: Sağ hizalı, sıfırla doldurulmuş

-w (width): Satır numarası için ayrılan alan genişliği. Varsayılan 6’dır.

-s (separator): Numara ile metin arasındaki ayraç. Varsayılan tab’dır.

-l (join blank lines): Kaç tane ardışık boş satırın tek boş satır olarak sayılacağını belirler.

-p: Mantıksal sayfa değişimlerinde numaralandırmayı sıfırlama. Bu parametre sıfırlamayı engeller.

Numaralandırma Stillerini Anlamak

Şimdi bu stilleri somut örneklerle görelim. Önce bir test dosyası oluşturalım:

cat > test_dosya.txt << 'EOF'
Birinci satir
Ikinci satir

Dorduncu satir (uc bos)
Besinci satir


Sekizinci satir (iki bos)
EOF

Şimdi farklı stilleri karşılaştıralım:

# Sadece dolu satırları numaralandir (varsayilan)
nl -b t test_dosya.txt

# Tum satirlari numaralandir
nl -b a test_dosya.txt

# Hic numaralandir ma
nl -b n test_dosya.txt

Birinci komutun çıktısında boş satırlar sayılmaz, ikinci komutta her satır sayılır. Bu fark özellikle büyük dosyalarda referans alırken önemlidir. Log dosyasındaki bir hata satırına “47. satırda şu var” derken nl -b a kullanırsan, editörün de aynı numarayı gösterir.

Regex tabanlı numaralandırma çok daha ileri bir kullanım sunar:

# Sadece "error" veya "warning" iceren satirlari numaralandir
nl -b p'error|warning' /var/log/uygulama.log

Bu komut, log dosyasında sadece hata ve uyarı satırlarını numaralandırır, diğer satırlar numarasız görünür ama yine de çıktıda yer alır. Bağlamı kaybetmeden sadece önemli satırları takip etmek için idealdir.

Format ve Görsel Düzenleme

Numara formatlamayı değiştirmek, özellikle raporlama için önemli olabilir.

# Sifirla doldurulmus, 4 haneli numaralar, nokta ayiraci
nl -n rz -w 4 -s '. ' /etc/hosts

Çıktı:

0001. 127.0.0.1   localhost
0002. 127.0.1.1   myhostname
0003. ::1         localhost

Bu format, çıktıyı bir rapora koyarken ya da CSV benzeri bir format üretirken çok kullanışlıdır.

Sol hizalı numara istersen:

nl -n ln -w 5 -s ' | ' /etc/hosts

Çıktı:

1     | 127.0.0.1   localhost
2     | 127.0.1.1   myhostname

Farklı bir başlangıç numarası ve artış miktarı belirlemek de mümkün:

# 100'den basla, 10'ar artir
nl -v 100 -i 10 test_dosya.txt

Bu kullanım, eski BASIC kodlarını hatırlatır, ama pratik olarak numaralandırılmış bölümlerde revizyonlara yer bırakmak için işe yarar.

Mantıksal Sayfalar: Gerçek Güç Buradan Geliyor

nl‘yi diğer araçlardan ayıran en önemli özelliği mantıksal sayfa konseptidir. Bir dosya, özel sınır satırları kullanılarak header, body ve footer bölümlerine ayrılabilir.

Sınırlar şöyle tanımlanır:

  • \:\:\: = Header başlangıcı
  • \:\: = Body başlangıcı
  • \: = Footer başlangıcı

Bu karakterler dosyada tam olarak bu şekilde yer almalıdır. Her yeni mantıksal sayfa başladığında numaralandırma sıfırlanır (varsayılan davranış).

cat > rapor_template.txt << 'EOF'
:::
AYLIK SISTEM RAPORU
Tarih: 2024-01
::
Sunucu: web01
CPU Kullanimi: %23
RAM Kullanimi: %67
Disk Kullanimi: %45
:
Rapor sonu - IT Departmani
EOF

nl -h a -b a -f a rapor_template.txt

Bu yapıda -h a header’ı, -b a body’yi, -f a footer’ı numaralandırır. Her bölüm kendi numaralandırma stilini alabilir, bu da karmaşık raporlar üretmek için güçlü bir mekanizma sağlar.

Numaralandırmayı sayfalarda sıfırlamak istemiyorsan -p kullanırsın:

nl -p -h a -b a -f a rapor_template.txt

Gerçek Dünya Senaryoları

Senaryo 1: Nginx Log Analizi

Bir web sunucusunda ani trafik artışı oluyor. Nginx error log’unu analiz etmen gerekiyor:

# Son 100 satirda kac tane 502 hatasi var ve hangi sirayla?
tail -100 /var/log/nginx/error.log | grep "502" | nl -b a -n rz -w 3 -s " >> "

Çıktıdaki son numara, sana hızlıca “son 100 satırda kaç 502 var” sorusunun cevabını verir. rz formatı ve >> ayracı çıktıyı görsel olarak daha okunabilir kılar.

Senaryo 2: Konfigürasyon Dosyası Karşılaştırması

Production ve staging ortamlarındaki sshd_config dosyalarını karşılaştırmadan önce her ikisini de numaralandırmak istiyorsun:

# Her iki dosyayi numaralandir, boş satırlar dahil
nl -b a -n rz -w 4 /etc/ssh/sshd_config_prod > /tmp/prod_numbered.txt
nl -b a -n rz -w 4 /etc/ssh/sshd_config_staging > /tmp/staging_numbered.txt

# Karsilastir
diff /tmp/prod_numbered.txt /tmp/staging_numbered.txt

Numaralandırılmış diff çıktısında hangi satırın değiştiğini hem diff’in gösterdiği numara hem de nl‘nin eklediği numara üzerinden çapraz doğrulayabilirsin.

Senaryo 3: Cron Job Çıktısı Raporlama

Bir backup script’inin çıktısını hem loglamak hem de okunabilir bir rapor oluşturmak için:

#!/bin/bash
BACKUP_LOG="/var/log/backup_$(date +%Y%m%d).log"

run_backup() {
    rsync -av /data/ /backup/ 2>&1
}

# Backup calistir, ciktisini numaralandir ve kaydet
run_backup | nl -b a -n rz -w 5 -s " | " | tee "$BACKUP_LOG"

# Satir sayisini ozet olarak ekle
echo "---" >> "$BACKUP_LOG"
echo "Toplam cikti satiri: $(wc -l < $BACKUP_LOG)" >> "$BACKUP_LOG"

Bu yaklaşımla log dosyasında her satıra kolayca referans verebilirsin. “47. satırdaki rsync hatası neydi?” sorusu anında yanıtlanabilir hale gelir.

Senaryo 4: Büyük Dosyalarda Bölüm Analizi

Binlerce satırlık bir Apache access log’unu analiz ediyorsun ve belirli HTTP status kodlarını bulmak istiyorsun, ama bağlamını da kaybetmek istemiyorsun:

# 500 hatalarini bul, satirlari numaralandir
# Sadece 500 satirlari numaralansin, diger satirlar gorunsun ama numarasiz kalasin
nl -b p'HTTP/[0-9.]+" 5[0-9][0-9]' /var/log/apache2/access.log | less

Ya da daha pratik bir yaklaşımla:

# 500 hatalarini cikar, numaralandir, ilk 20'sini goster
grep ' 5[0-9][0-9] ' /var/log/apache2/access.log | 
  nl -b a -n rz -w 4 | 
  head -20

Senaryo 5: Script Hata Ayıklama

Uzun bir bash script’i hata ayıklama amacıyla numaralandırmak istiyorsun:

# Script dosyasini numaralandir, yorum satirlari dahil
nl -b a -n rz -w 4 -s "  " benim_scriptim.sh | less

# Sadece yorum olmayan satirlari numaralandir (# ile baslamayanlar)
nl -b p'^[^#]' -n rz -w 4 benim_scriptim.sh

İkinci komut, yorum satırlarını atlar ve sadece aktif kod satırlarını numaralandırır. Büyük script’lerde gerçek mantık satırı sayısını hızlıca görmek için kullanışlıdır.

nl ile Pipe Zincirleri

nl pipe zincirlerinde gerçek potansiyelini gösterir. Birkaç pratik kombinasyon:

# Sistem servislerini listele, sadece aktif olanlari numaralandir
systemctl list-units --type=service --state=active | 
  grep "active running" | 
  nl -b a

# /etc dizinindeki tum .conf dosyalarini numaralandir
find /etc -name "*.conf" -type f | sort | nl -b a -n rz -w 3

# ps ciktisini numaralandir, header'i atla
ps aux | tail -n +2 | nl -b a -v 0 -n rz -w 4

Son örnekte -v 0 ile numaralandırmayı 0’dan başlatıyoruz, böylece satır numarası process sırası gibi okunuyor.

# En fazla CPU kullanan 10 processi numaralandirilmis goster
ps aux --sort=-%cpu | head -11 | nl -b a

awk ve sed ile Birlikte Kullanım

nl tek başına güçlü olsa da, awk ve sed ile kombinasyonu çok daha zengin işlemler yapmanı sağlar:

# nl ile numaralandir, sonra awk ile belirli aralikları filtrele
nl -b a /var/log/syslog | awk 'NR >= 100 && NR <= 150'

# Numaralandirilmis ciktida sadece ciftr numarali satirlari goster
nl -b a /etc/passwd | awk 'NF > 0 && $1 % 2 == 0'

# sed ile numara formatini degistir
nl -b a test_dosya.txt | sed 's/^ */[/' | sed 's/t/] /'

Son komut satır numaralarını köşeli parantez içine alır: [1] İçerik formatı. Bu format bazı log inceleme araçlarıyla daha uyumlu çalışır.

cat -n ile Karşılaştırma

Birçok sysadmin cat -n alışkanlığından vazgeçmez, ama iki araç arasındaki farkı bilmek önemlidir.

# cat -n tum satirlari numaralandirir, bos satirlar dahil
cat -n test_dosya.txt

# nl varsayilan olarak bos satirlari atlar
nl test_dosya.txt

# nl'yi cat -n gibi davrandirmak icin
nl -b a test_dosya.txt

cat -n daha basit ama daha az esnektir. Format seçeneği yoktur, başlangıç numarası belirleyemezsin, regex tabanlı numaralandırma yapamazsın. Hızlı bir kontrol için cat -n yeterlidir, ama ciddi metin işleme veya raporlama ihtiyaçlarında nl tercih edilmeli.

Performans ve Büyük Dosyalar

Büyük log dosyalarında nl performansı önemli bir konudur. Genel kural şudur: nl satırı okuyup işlemek zorunda olduğundan, çok büyük dosyalarda (1GB+) dikkatli kullanılmalıdır.

# Buyuk dosyalarda once filtrele, sonra numaralandir
grep "ERROR" /var/log/uygulama.log | nl -b a

# Dogrudan buyuk dosyayi nl'den gecirmek yerine
# once gereksiz satirlari at
grep -v "^$" /var/log/buyuk_dosya.log | 
  grep -v "^#" | 
  nl -b a -n rz -w 6

Bu yaklaşım hem bellek hem de işlemci açısından daha verimlidir.

Pratik İpuçları

Günlük hayatta sık kullandığım birkaç ipucu:

Alias tanımlamak: En çok kullandığın formatı alias olarak kaydetmek zaman kazandırır.

# .bashrc veya .bash_aliases dosyasina ekle
alias nll='nl -b a -n rz -w 4 -s " | "'
alias nlc='nl -b a -n rz -w 6'

Renklendirme ile birleştirme: nl çıktısını grep --color ile pipe’layarak belirli satırları renklendire bilirsin.

nl -b a /var/log/syslog | grep --color=always "error|warning|critical"

Çıktıyı dosyaya kaydetme: Numaralandırılmış çıktıyı dosyaya kaydet, sonra referans için kullan.

nl -b a -n rz -w 5 /etc/nginx/nginx.conf > /tmp/nginx_numbered_$(date +%Y%m%d).txt

Sonuç

nl komutu, terminal’de metin işlemenin sessiz kahramanlarından biridir. Yüzeysel bakıldığında sadece satır numarası ekleyen basit bir araç gibi görünür, ama derinlemesine incelendiğinde esnek biçimlendirme seçenekleri, regex tabanlı numaralandırma, mantıksal sayfa desteği ve pipe uyumluluğuyla çok daha kapsamlı bir araç olduğu anlaşılır.

Günlük sysadmin işlerinde en çok değer katacağı alanlar şunlar: log analizi sırasında referans satır numaraları oluşturmak, konfigürasyon dosyalarını paylaşırken belirli satırlara işaret etmek, script çıktılarını numaralandırılmış raporlara dönüştürmek ve büyük dosyalarda regex tabanlı önemli satırları işaretlemek.

cat -n alışkanlığından vazgeçmek zor gelse de, nl‘yi öğrenmek için harcanan birkaç saatlik pratik, uzun vadede ciddi zaman tasarrufu sağlar. Özellikle script otomasyonlarında ve log analiz rutinlerinde nl‘yi araç kutuna eklemek, işlerin kalitesini ve hızını gözle görülür biçimde artırır.

Yorum yapın