5.000 işlem == 1 Satır…
… yada 5 ömür == 1 Dakika.
Bazı işlemleri, bir değil beş ömrünüz de olsa, “Teknolojiyi” (doğru) kullanmadan yapamazsınız (burada Teknoloji == Uçbirim || Kabuk || Komut satırı || Komut || Regex
anlamına geliyor). Bu Teknolojilerin kullanımına bir giriş yapalım.
Soru:
➊ Mesela, 500 bin dizede, 5 milyon “değiştirme” (substitution) işlemini kaç zamanda yaparsınız?
➋ Peki ya “Teknolojiyi” kulanarak?
Cevap:
➊ Denemedim hiç. Hesaplamasıda çok zor (işlemlere, araçlara ve çalışma tekniğine/performansına bağlı).
Ama, tahminen Uzuuuun bir süre.
➋ Denedim çoğu kez. Hesaplaması üç aşağı beş yukarı mümkün (işlemlere/komutlara, bilgisayar’a vs bağlı tabi).
Tahminen asgari 5-10 saniye, azami 5-10 dakika.
Bu tarz işlemleri (verimli bir şekilde) uygulamak için en önemli “Teknolojinin” ismi regex
(Regular Expressions).
`regex` nedir?
regex
konusunu (alnatım, örnekleme) ileride ele almayı düşündüğümden (aksilik kıçmazsa), özet bir tanım yapayım:
regex
, regex
-sözdizimi kurallarını işleyen kütüphanelerin genel ismi (çeşitleri var, mesela pcre
).
Kısaca regex
kullanımı adımları:
-
desen
tanımla/tasarla:
regex
-sözdizimi kurallarına uygun birdesen
tanımla -
komut
'a “ver”:
tanımladığındesen
'i birkomut
'a “ver” -
komut
görevini yapsın:
komut
desen
'i bulup, görevini yapsın (mesela değişim işlemi (substitution))
NOT: “Sunuma” hizmet etsin diye adımları numaralandırdım. Tasarlanan desen
bir komut
ile kullanılacaksa (Python
gibi bir yazılım dilinde değil yani), genelde bu adımlar tek bir "komut
ve argümanları
" tarzında şekillenir, ve 2)'ci noktanın doğruluğu sorgulanabilir. Örneğin:
# ➊ ➋ ➌
grep 'Mehmet Yer' Mehmet*2018*
➊ Komut – Mesela grep
, sed
, awk
, find
, …
➋ regex-deseni
– Genel-Geçerli bilgi vermek zor. Değişik komutlar değişik regex-versiyonları
kullanabiliyor.
➌ kabuk-deseni
– bash-kabuğu
'nda kullanabileceğin desenler için bak: GNU Bash Kılavuzu: Pattern Matching
Konuyu, birkaç örnek ile, biraz açalım:
Senaryo – 5.000 `txt`-dosyasında değişiklik yap:
Tanım:
- Bir klasörde 5.000 tane txt-dosyası var.
- Sadece dosya-ismi ‘
Mehmet
’ adı ile başlayıp ‘2018
’ sayısını içeren her bir dosyada, “Mehmet Yer
” ismini “Mehmet Er
” olarak değiştir.
Işlem:
Binbir yolu var. Işte bir iki tanesi.
DIKKAT: Lütfen notlara dikkat edin ve önemli dosyalar üzerinde herhangi bir işlem yapmadan önce DAIMA dosyaları yedekleyin!
Eğer dosyalar uçbirimde bulunduğunuz klasörün içinde ise ...
… yani örneğin komut satırına pwd
yazıp Enter
tuşuna bastığınızda geri bildirilen patika
/home/SIZINISMINIZ/dosyanın/patikası
ise, ve dosyalarınızda aynı patika
'nın içinde ise
/home/SIZINISMINIZ/dosyanın/patikası:
Ahmet-Zengin-2017.txt
Derya-Deniz-2018.txt
Derya-Deniz-2017.txt
Mehmet-Yer-2018.txt
Mehmet-Er-2017.txt
Mehmet-Er-2016.txt
Özgün-Kobay-2018.txt
Özgün-Kobay-2017.txt
… bu komutları kullanabilirsiniz:
`sed`
NOT: Işlemi (kalıcı olarak -i
) gerçekleştirmeden önce, desen
'in (pattern) uyup uymadığını denemek istiyorsanız, -i
opsiyonunu silerek komutu çalıştırın. Eğer kullandığınız desen
'in istediğiniz sonucu verdiğinden emin olduysanız, aynı komutu tekrar -i
opsiyonunu ekleyerek çalıştırın.
# Önce 'desen'i dene. '-i' opsiyonu işlem sonucunu direk dosyada uygular:
sed 's/Mehmet\s*Yer/Mehmet Er/g' Mehmet*2018*
# veya
sed 's/\<Mehmet\>\s*\<Yer\>/Mehmet Er/g' Mehmet*2018*
Eğer bir desen
istediğiniz sonucu verdi ise, -i
opsiyonunu tekrar ekleyerek değişikliği direk dosyaya uygulayın:
# En basit hali. Pek güvenli (tanım 'kesin' değil) sayılmaz.
sed -i 's/Mehmet\s*Yer/Mehmet Er/g' Mehmet*
# Biraz daha güvenli
sed -i 's/\<Mehmet\>\s*\<Yer\>/Mehmet Er/g' Mehmet*
Eğer dosyalar başka bir yerde (patika
) ise, mesela şu komutları kullanabilirsiniz:
`find` ve `sed`
find Dosyaların/PATIKASI -type f -name "Mehmet*2018*" -exec sed 's/\<Mehmet\>\s*\<Yer\>/Mehmet Yer/g' '{}' \;
Devamı:
Deney ortamı oluşturan bir betik bitti sayılır. Yakında eklerim.
Şimdilik bu kadar