Ana içeriğe geç

Linux'ta dosyalar içinde arama yapma#

İki farklı soru var, ve ikisinin cevabı da farklı komutta: "bu isimde bir dosya nerede" ile "bu metni hangi dosya içeriyor" aynı şey değil. find birinciyi, grep -r ikinciyi çözer - ve çoğu zaman ikisini birlikte kullanmanız gerekir.

Dosya adına göre arama: find#

find /var/www -name "*.log"

/var/www altında, alt dizinler dahil, adı .log ile biten her dosyayı bulur. Büyük/küçük harf duyarsız arama için -iname:

find /var/www -iname "*.PHP"

En sık kullanılan find filtreleri#

find /home -type f -name "*.conf"        # yalnızca dosyalar, dizinler değil
find /home -type d -name "cache"          # yalnızca "cache" adlı dizinler
find /var/log -type f -mtime -7           # son 7 gün içinde değişen dosyalar
find /var/log -type f -size +100M         # 100MB'tan büyük dosyalar
find / -user www-data 2>/dev/null         # www-data'ya ait dosyalar

-mtime -7 "7 günden daha yeni", -mtime +7 ise "7 günden daha eski" demektir - artı/eksi işareti kolayca ters okunur, dikkat edin.

find'ın bulduklarıyla bir şey yapmak: -exec

find /var/log -name "*.log" -mtime +30 -exec rm {} \;

30 günden eski tüm .log dosyalarını siler. {} bulunan her dosyanın yerine geçer, \; komutun sonunu işaretler. Silme gibi geri dönüşü olmayan işlemlerden önce -exec rm yerine önce -print ile ne sileceğinizi görün.

Dosya içeriğine göre arama: grep -r#

grep -r "ERROR" /var/log/nginx/

Bir dizin altındaki tüm dosyaları, alt dizinler dahil, tarayıp içinde "ERROR" geçen satırları basar. Kullanışlı ekler:

grep -rn "ERROR" /var/log/nginx/          # satır numarasıyla birlikte
grep -rl "ERROR" /var/log/nginx/          # yalnızca eşleşen dosya adları, satırlar değil
grep -ri "error" /var/log/nginx/          # büyük/küçük harf duyarsız
grep -r --include="*.log" "ERROR" /var/log/   # yalnızca .log uzantılı dosyalarda ara
grep -r --exclude-dir=node_modules "TODO" .   # bu dizini tarama dışı bırak

-l (küçük L) özellikle işe yarar: "bu metni hangi dosyalar içeriyor" sorusuna liste olarak cevap verir, binlerce satırlık grep -r çıktısında boğulmazsınız.

İkisini birleştirmek: find + grep#

Belirli bir dosya türünde arama yapmak isteyip --include yeterince esnek gelmiyorsa:

find . -name "*.php" -exec grep -l "eval(" {} \;

.php uzantılı dosyaların içinde eval( geçenleri bulur - kötü niyetli/şüpheli kod aramak için klasik bir kalıp.

Daha hızlısı var: ripgrep (rg)#

Büyük bir dizin ağacında (özellikle node_modules, .git gibi klasörler varsa) grep -r gözle görülür yavaşlar. ripgrep, .gitignore'u otomatik atlayarak ve paralel tarayarak genelde kat kat hızlıdır:

sudo apt install -y ripgrep    # Ubuntu/Debian
sudo dnf install -y ripgrep    # Rocky/AlmaLinux
rg "ERROR" /var/log/nginx/

Sözdizimi grepe çok benzer, .gitignore/.ignore dosyalarını otomatik saygı göstermesi ve varsayılan olarak rekürsif olması en büyük fark.

Morpheus ile

"/var/log altında son 24 saatte değişen tüm .log dosyalarını listele"

"nginx log'larında 'connection refused' geçen satırları bul"

Morpheus bu ikisini de tek istekle çalıştırır - find ile grepi ayrı ayrı yazmanıza gerek kalmaz.

Kontrol listesi#

  • [ ] Dosya adı arıyorsanız find, içerik arıyorsanız grep -r kullandınız
  • [ ] Büyük dizin ağaçlarında (node_modules, .git) hız sorunuysa ripgrepi denediniz
  • [ ] -exec rm gibi geri dönüşsüz işlemlerden önce -print ile önizleme yaptınız