Bagaimana cara Combine find dan grep untuk pencarian yang kompleks? (GNU / linux, find, grep)

17

Saya mencoba melakukan pencarian teks di beberapa file yang berbagi struktur direktori yang sama, tetapi tidak di pohon direktori yang sama, di GNU / Linux.

Saya memiliki server web dengan banyak situs yang memiliki struktur pohon yang sama (kerangka kerja PHP MV Code Igniter), jadi saya ingin mencari di direktori tertentu di bawah pohon untuk setiap situs, contoh:

/srv/www/*/htdocs/system/application/

Di mana * adalah nama situs. Dan dari direktori aplikasi itu , saya ingin mencari semua pohon sampai ke daunnya, untuk file * .php yang memiliki beberapa pola teks di dalamnya, katakanlah "debug (", tidak perlu ekspresi reguler.

Saya tahu cara menggunakan find dan grep tetapi saya tidak pandai menggabungkannya.

Bagaimana saya melakukan ini?
Terima kasih sebelumnya!

Petruza
sumber

Jawaban:

21

Mencoba

find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep "debug (" {} \; -print

Ini harus secara rekursif mencari folder di bawah applicationuntuk file dengan .phpekstensi dan meneruskannya grep.

Optimalisasi untuk ini adalah dengan mengeksekusi:

find /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep -H "debug ("

Ini digunakan xargsuntuk meneruskan semua .phpfile keluaran findsebagai argumen untuk satu grepperintah; misalnya ,. The pilihan dan pilihan untuk memastikan spasi pada nama file dan direktori ditangani dengan benar. The pilihan diteruskan ke memastikan bahwa nama file yang dicetak dalam segala situasi. (Secara default, mencetak nama file hanya ketika beberapa argumen dilewatkan.)grep "debug (" file1 file2 file3-print0find-0xargs-Hgrepgrep

Dari man xargs:

-0

      Item input diakhiri oleh karakter nol alih-alih oleh spasi, dan tanda kutip dan garis miring terbalik tidak khusus (setiap karakter diambil secara harfiah). Menonaktifkan akhir string file, yang diperlakukan seperti argumen lain. Berguna ketika item input mungkin mengandung spasi, tanda kutip, atau garis miring terbalik. -print0Opsi menemukan GNU menghasilkan input yang cocok untuk mode ini.

Nagul
sumber
1
+1. Itu akan menjalankan grep untuk setiap file php. Jika ada banyak file, Anda dapat mengoptimalkan lebih lanjut olehfind /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep "debug ("
Jukka Matilainen
@jackem Setuju. Saya akan memperbarui jawaban saya sesuai.
nagul
2
Peningkatan kecil lainnya: xargs mungkin hanya meneruskan satu nama file ke grep, dalam hal ini grep tidak akan menampilkan nama file jika ada kecocokan. Anda mungkin ingin menambahkan -H pada perintah grep untuk memaksanya menampilkan nama file.
Randy Orrison
@Randy Itu poin yang sangat valid.
nagul
3
Ini benar-benar necromancy, tetapi GNU finddapat mengambil +operator alih-alih \;melakukan jenis eksekusi proses yang xargssama yang dilakukan. Jadi, find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +lakukan hal yang sama seperti xargscontoh dalam jawaban ini, tetapi dengan satu proses garpu yang lebih sedikit (dan masih 0 risiko untuk masalah nama file).
Daniel Andersson
10

findbahkan tidak diperlukan untuk contoh ini, orang dapat menggunakan grepsecara langsung (setidaknya GNU grep):

grep -RH --include='*.php' "debug (" /srv/www/*/htdocs/system/application/

dan kita menuju satu proses garpu.

Pilihan:

  • -R, --dereference-recursive Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
  • -H, --with-filename Print the file name for each match. This is the default when there is more than one file to search.
  • --include=GLOB Search only files whose base name matches GLOB (using wildcard matching as described under --exclude).
  • --exclude=GLOB Skip any command-line file with a name suffix that matches the pattern GLOB, using wildcard matching; a name suffix is either the whole name, or any suffix starting after a / and before a +non-/. When searching recursively, skip any subfile whose base name matches GLOB; the base name is the part after the last /. A pattern can use *, ?, and [...] as wildcards, and \ to quote a wildcard or backslash character literally.
Daniel Andersson
sumber
Hanya untuk rasa ingin tahu, apa -RHartinya opsi?
Gus
@Gus: Menambahkan man grepkutipan deskripsi opsi ke posting.
Daniel Andersson
0

Shell Anda dapat menemukan file php dan memberikannya kepada grep. Dalam bash:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
user2394284
sumber