Cukup ketik "man grep" dan Anda akan melihat opsi --exclude, dan --exclude-dir terdaftar di sana - dari judul pertanyaan ini, saya berasumsi Anda sudah tahu tentang grep ...
arcseldon
35
Jika Anda mengambil kode dalam repositori git dan node_modulesberada di Anda .gitignore, git grep "STUFF"adalah cara termudah. git grepmencari file yang dilacak di pohon yang berfungsi, mengabaikan semuanya dari.gitignore
0xcaff
2
Contoh untuk simpul: grep -R --exclude-dir={node_modules,bower_components} "MyString" | cut -c1-"$COLUMNS"- selanjutnya Anda selalu bisa alias ini di shell untuk 'nodegrep' atau apa pun dan menggunakan argumen perintah sebagai input string ..
bshea
Jawaban:
395
SOLUSI 1 (gabungkan finddan grep)
Tujuan dari solusi ini bukan untuk menangani grepkinerja tetapi untuk menunjukkan solusi portabel: juga harus bekerja dengan busybox atau versi GNU yang lebih tua dari 2,5.
Gunakan find, untuk mengecualikan direktori foo and bar:
Anda sudah tahu solusi ini, tetapi saya menambahkannya karena ini solusi terbaru dan efisien. Perhatikan ini adalah solusi yang kurang portabel tetapi lebih dapat dibaca manusia.
Untuk mengecualikan beberapa direktori, gunakan --exclude-dirsebagai:
--exclude-dir={node_modules,dir1,dir2,dir3}
SOLUSI 3 (Ag)
Jika Anda sering mencari melalui kode, Ag (The Silver Searcher) adalah alternatif yang jauh lebih cepat daripada grep, yang disesuaikan untuk mencari kode. Misalnya, secara otomatis mengabaikan file dan direktori yang terdaftar .gitignore, sehingga Anda tidak harus terus melewati opsi pengecualian yang rumit untuk grepatau find.
kombinasi ini mencari lebih cepat daripada --exclude-dir=dirdan itu menunjukkan hasil dengan warna - mudah dibaca
Maxim Yefremov
27
"kombinasi ini" find ... -exectidak lebih cepat dari grep --exclude-dirpada saya. Keuntungan besar untuk grep (sekitar lima kali lebih cepat dengan file 26k +, disaring dari 38k + pada HDD), kecuali Anda mengganti \;dengan +untuk combo find / exec. Maka grep "hanya" sekitar 30% lebih cepat. Sintaks grep juga dapat dibaca manusia :).
Kjell Andreassen
Setuju, karena ini jelas. Beberapa busyboxes tidak memiliki perintah GREP.
hornetbzz
10
juga mencatat bahwa Anda dapat mengecualikan beberapa dengan--exclude-dir={dir1,dir2}
suh
4
Saya tidak sedikit terkejut bahwa itu node_modulesadalah contoh kanonik.
@Manocho: Jika menurut Anda ackhebat, coba The Silver Searcher dan lihat kecepatannya meningkat!
Johnsyweb
30
Sintaks untuk yang tidak sabar: --exclude-dir=dirmenggunakan greppola ekspresi reguler, bukan globbing file shell. Pola bekerja di jalur relatif ke direktori Anda saat ini. Jadi gunakan pola --exclude-dir=dir, bukan --exclude-dir="/root/dir/*".
tanius
15
Jika Anda ingin mengecualikan beberapa dir dari pencarian, apakah ada opsi yang lebih baik daripada menggunakan $ grep -r --exclude-dir=dir1 --exclude-dir=dir2 "string" /path/to/search/dir:?
Darshan Chaudhary
4
Saya mungkin menghabiskan terlalu banyak waktu untuk hal ini daripada orang waras, tapi saya tidak bisa seumur hidup mencari tahu bagaimana mengecualikan subdirektori dari pencarian - grep -r --exclude-dir=public keyword .bekerja, tetapi grep -r --exclude-dir='public/dist' keyword .tidak. Saya mencoba menambahkan regex wildcard, melarikan diri karakter dll, tetapi sepertinya tidak ada yang membantu.
dkobozev
73
Kecualikan beberapa direktori seperti:grep -r "Request" . --exclude-dir={node_modules,git,build}
maverick97
78
Jika Anda ingin mengecualikan beberapa direktori :
"r" untuk rekursif, "l" untuk mencetak hanya nama file yang mengandung kecocokan dan "i" untuk mengabaikan perbedaan huruf besar-kecil:
Contoh: Saya ingin mencari file yang mengandung kata 'halo'. Saya ingin mencari di semua direktori linux saya kecuali direktori proc , direktori boot , direktori sys dan direktori root :
CATATAN: jangan tambahkan spasi setelah koma di{dir1,dir2,dir3}
skplunkerin
Terima kasih, berguna saat menerima melalui ruang kerja SVN:grep -Irsn --exclude-dir=.svn 'foo' .
RAM237
1
Anda bisa memberikan --exclude-diropsi beberapa kali.
Walf
45
Sintaks ini
--exclude-dir={dir1,dir2}
diperluas oleh shell (misalnya Bash), bukan oleh grep, ke dalam ini:
--exclude-dir=dir1 --exclude-dir=dir2
Mengutip akan mencegah shell mengembangkannya, jadi ini tidak akan berfungsi:
--exclude-dir='{dir1,dir2}' <-- this won't work
Pola yang digunakan dengan pola --exclude-diryang sama dijelaskan dalam halaman manual untuk --excludeopsi:
--exclude=GLOB
Skip files whose base name matches GLOB (using wildcard matching).
A file-name glob can use *, ?, and [...] as wildcards, and \ to
quote a wildcard or backslash character literally.
Shell umumnya akan mencoba mengembangkan pola seperti itu sendiri, jadi untuk menghindari ini, Anda harus mengutipnya:
--exclude-dir='dir?'
Anda dapat menggunakan kurung kurawal dan mengutip dengan mengecualikan pola bersama seperti ini:
--exclude-dir={'dir?','dir??'}
Pola dapat menjangkau beberapa segmen jalur:
--exclude-dir='some*/?lse'
Ini akan mengecualikan direktori seperti topdir/something/else.
grepdapat digunakan bersamaan dengan -r(rekursif), i(abaikan case) dan -o(hanya mencetak bagian yang cocok dari garis). Untuk mengecualikan filespenggunaan --excludedan untuk mengecualikan direktori gunakan --exclude-dir.
Menyatukannya Anda berakhir dengan sesuatu seperti:
Menggambarkannya membuatnya terdengar jauh lebih rumit daripada yang sebenarnya. Lebih mudah diilustrasikan dengan contoh sederhana.
Contoh:
Misalkan saya sedang mencari proyek saat ini untuk semua tempat di mana saya secara eksplisit menetapkan nilai string debuggerselama sesi debugging, dan sekarang ingin meninjau / menghapus.
Saya menulis sebuah skrip yang dipanggil findDebugger.shdan digunakan grepuntuk menemukan semua kejadian. Namun:
Untuk pengecualian file - Saya ingin memastikan bahwa .eslintrcdiabaikan (ini sebenarnya memiliki aturan linting debuggersehingga harus dikecualikan). Demikian juga, saya tidak ingin skrip saya sendiri dirujuk dalam hasil apa pun.
Untuk pengecualian direktori - Saya ingin mengecualikan node_moduleskarena berisi banyak perpustakaan yang melakukan referensi debuggerdan saya tidak tertarik dengan hasil tersebut. Juga saya hanya ingin menghilangkan .ideadan .gitmenyembunyikan direktori karena saya juga tidak peduli dengan lokasi pencarian tersebut, dan ingin tetap menjadi pemain pencarian.
Jadi di sini adalah hasilnya - saya membuat skrip bernama findDebugger.shdengan:
Saya percaya opsi "r" harus dicetak dengan huruf besar "-R".
hornetbzz
1
Menarik. "r" selalu bekerja untuk saya di nix dan mac.
arcseldon
Ketika saya menulis jawaban saya , saya menggunakan -R(saya tidak ingat mengapa sekarang). Saya biasanya menggunakan -r. Ternyata versi huruf besar mengikuti symlinks . TIL.
Johnsyweb
@ Johnsyweb - terima kasih. memutakhirkan jawaban Anda - jangan ingat kapan, kemungkinan pada tahun 2016 ketika saya menambahkan jawaban ini :)
arcseldon
10
Anda dapat mencoba sesuatu seperti grep -R search . | grep -v '^node_modules/.*'
Dalam beberapa kasus bukan solusi yang bagus. Sebagai contoh: Jika direktori 'node_modules' adalah direktori besar dengan banyak kecocokan positif palsu (maka kebutuhan untuk menyaring direktori) maka grep pertama menghabiskan banyak waktu mencari melalui sub-direktori dan KEMUDIAN grep filtering kedua keluar pertandingan. Lebih cepat untuk mengecualikan node_modules di grep pertama itu sendiri.
GuruM
2
saya tidak peduli tentang kelambatan, saya bisa melihat perintah dan tahu apa fungsinya
Funkodebat
1
Ditto untuk komentar Guru. Grep /varhang ketika hits /var/rundalam kasus saya. Karenanya alasan saya ingin menghindari direktori di tempat pertama.
jww
3
--exclude-diradalah solusi terbaik pada 2016.
Omar Tariq
10
Jika Anda mengambil kode di repositori git dan node_modulesberada di Anda .gitignore, Anda dapat menggunakannya git grep. git grepmencari file yang dilacak di pohon yang berfungsi, mengabaikan semuanya.gitignore
Banyak jawaban yang benar telah diberikan di sini, tetapi saya menambahkan yang ini untuk menekankan satu poin yang menyebabkan beberapa upaya tergesa-gesa untuk gagal sebelumnya: exclude-dirmengambil pola , bukan jalur ke direktori.
Katakanlah pencarian Anda adalah:
grep -r myobject
Dan Anda perhatikan bahwa output Anda berantakan dengan hasil dari src/other/objects-folder. Perintah ini tidak akan memberi Anda hasil yang diinginkan:
Dan Anda mungkin bertanya-tanya mengapa exclude-dirtidak bekerja! Untuk benar-benar mengecualikan hasil dari objects-folder, cukup lakukan ini:
grep -r myobject --exclude-dir=objects-folder
Dengan kata lain, cukup gunakan nama folder , bukan path. Jelas sekali Anda mengetahuinya.
Dari halaman manual:
--exclude-dir = GLOB
Lewati direktori baris perintah dengan akhiran nama yang cocok dengan pola GLOB. Saat mencari secara rekursif, lewati setiap subdirektori yang nama dasarnya cocok dengan GLOB. Abaikan pemotongan garis miring yang berlebihan di GLOB.
node_modules
berada di Anda.gitignore
,git grep "STUFF"
adalah cara termudah.git grep
mencari file yang dilacak di pohon yang berfungsi, mengabaikan semuanya dari.gitignore
grep -R --exclude-dir={node_modules,bower_components} "MyString" | cut -c1-"$COLUMNS"
- selanjutnya Anda selalu bisa alias ini di shell untuk 'nodegrep' atau apa pun dan menggunakan argumen perintah sebagai input string ..Jawaban:
SOLUSI 1 (gabungkan
find
dangrep
)Tujuan dari solusi ini bukan untuk menangani
grep
kinerja tetapi untuk menunjukkan solusi portabel: juga harus bekerja dengan busybox atau versi GNU yang lebih tua dari 2,5.Gunakan
find
, untuk mengecualikan direktori foo and bar:Kemudian gabungkan
find
dan penggunaan non-rekursifgrep
, sebagai solusi portabel:SOLUSI 2 (penggunaan rekursif
grep
):Anda sudah tahu solusi ini, tetapi saya menambahkannya karena ini solusi terbaru dan efisien. Perhatikan ini adalah solusi yang kurang portabel tetapi lebih dapat dibaca manusia.
Untuk mengecualikan beberapa direktori, gunakan
--exclude-dir
sebagai:--exclude-dir={node_modules,dir1,dir2,dir3}
SOLUSI 3 (Ag)
Jika Anda sering mencari melalui kode, Ag (The Silver Searcher) adalah alternatif yang jauh lebih cepat daripada grep, yang disesuaikan untuk mencari kode. Misalnya, secara otomatis mengabaikan file dan direktori yang terdaftar
.gitignore
, sehingga Anda tidak harus terus melewati opsi pengecualian yang rumit untukgrep
ataufind
.sumber
--exclude-dir=dir
dan itu menunjukkan hasil dengan warna - mudah dibacafind ... -exec
tidak lebih cepat darigrep --exclude-dir
pada saya. Keuntungan besar untuk grep (sekitar lima kali lebih cepat dengan file 26k +, disaring dari 38k + pada HDD), kecuali Anda mengganti\;
dengan+
untuk combo find / exec. Maka grep "hanya" sekitar 30% lebih cepat. Sintaks grep juga dapat dibaca manusia :).--exclude-dir={dir1,dir2}
node_modules
adalah contoh kanonik.Versi terbaru GNU Grep (> = 2.5.2 ) menyediakan:
yang mengecualikan direktori yang cocok dengan pola
dir
dari pencarian direktori rekursif.Jadi kamu bisa melakukan:
Untuk informasi lebih lanjut tentang sintaks dan penggunaan, lihat
Untuk GNU Greps dan POSIX Grep yang lebih lama , gunakan
find
seperti yang disarankan dalam jawaban lain.Atau cukup gunakan
ack
( Edit : atau The Silver Searcher ) dan selesai saja!sumber
ack
hebat, coba The Silver Searcher dan lihat kecepatannya meningkat!--exclude-dir=dir
menggunakangrep
pola ekspresi reguler, bukan globbing file shell. Pola bekerja di jalur relatif ke direktori Anda saat ini. Jadi gunakan pola--exclude-dir=dir
, bukan--exclude-dir="/root/dir/*"
.$ grep -r --exclude-dir=dir1 --exclude-dir=dir2 "string" /path/to/search/dir
:?grep -r --exclude-dir=public keyword .
bekerja, tetapigrep -r --exclude-dir='public/dist' keyword .
tidak. Saya mencoba menambahkan regex wildcard, melarikan diri karakter dll, tetapi sepertinya tidak ada yang membantu.grep -r "Request" . --exclude-dir={node_modules,git,build}
Jika Anda ingin mengecualikan beberapa direktori :
"r" untuk rekursif, "l" untuk mencetak hanya nama file yang mengandung kecocokan dan "i" untuk mengabaikan perbedaan huruf besar-kecil:
Contoh: Saya ingin mencari file yang mengandung kata 'halo'. Saya ingin mencari di semua direktori linux saya kecuali direktori proc , direktori boot , direktori sys dan direktori root :
Catatan: Contoh di atas harus root
Catatan 2 (menurut @skplunkerin): jangan tambahkan spasi setelah koma masuk
{dir1,dir2,dir3}
sumber
{dir1,dir2,dir3}
grep -Irsn --exclude-dir=.svn 'foo' .
--exclude-dir
opsi beberapa kali.Sintaks ini
diperluas oleh shell (misalnya Bash), bukan oleh
grep
, ke dalam ini:Mengutip akan mencegah shell mengembangkannya, jadi ini tidak akan berfungsi:
Pola yang digunakan dengan pola
--exclude-dir
yang sama dijelaskan dalam halaman manual untuk--exclude
opsi:Shell umumnya akan mencoba mengembangkan pola seperti itu sendiri, jadi untuk menghindari ini, Anda harus mengutipnya:
Anda dapat menggunakan kurung kurawal dan mengutip dengan mengecualikan pola bersama seperti ini:
Pola dapat menjangkau beberapa segmen jalur:
Ini akan mengecualikan direktori seperti
topdir/something/else
.sumber
Sering menggunakan ini:
grep
dapat digunakan bersamaan dengan-r
(rekursif),i
(abaikan case) dan-o
(hanya mencetak bagian yang cocok dari garis). Untuk mengecualikanfiles
penggunaan--exclude
dan untuk mengecualikan direktori gunakan--exclude-dir
.Menyatukannya Anda berakhir dengan sesuatu seperti:
Menggambarkannya membuatnya terdengar jauh lebih rumit daripada yang sebenarnya. Lebih mudah diilustrasikan dengan contoh sederhana.
Contoh:
Misalkan saya sedang mencari proyek saat ini untuk semua tempat di mana saya secara eksplisit menetapkan nilai string
debugger
selama sesi debugging, dan sekarang ingin meninjau / menghapus.Saya menulis sebuah skrip yang dipanggil
findDebugger.sh
dan digunakangrep
untuk menemukan semua kejadian. Namun:Untuk pengecualian file - Saya ingin memastikan bahwa
.eslintrc
diabaikan (ini sebenarnya memiliki aturan lintingdebugger
sehingga harus dikecualikan). Demikian juga, saya tidak ingin skrip saya sendiri dirujuk dalam hasil apa pun.Untuk pengecualian direktori - Saya ingin mengecualikan
node_modules
karena berisi banyak perpustakaan yang melakukan referensidebugger
dan saya tidak tertarik dengan hasil tersebut. Juga saya hanya ingin menghilangkan.idea
dan.git
menyembunyikan direktori karena saya juga tidak peduli dengan lokasi pencarian tersebut, dan ingin tetap menjadi pemain pencarian.Jadi di sini adalah hasilnya - saya membuat skrip bernama
findDebugger.sh
dengan:sumber
-R
(saya tidak ingat mengapa sekarang). Saya biasanya menggunakan-r
. Ternyata versi huruf besar mengikuti symlinks . TIL.Anda dapat mencoba sesuatu seperti
grep -R search . | grep -v '^node_modules/.*'
sumber
/var
hang ketika hits/var/run
dalam kasus saya. Karenanya alasan saya ingin menghindari direktori di tempat pertama.--exclude-dir
adalah solusi terbaik pada 2016.Jika Anda mengambil kode di repositori git dan
node_modules
berada di Anda.gitignore
, Anda dapat menggunakannyagit grep
.git grep
mencari file yang dilacak di pohon yang berfungsi, mengabaikan semuanya.gitignore
sumber
Sangat berguna, terutama bagi mereka yang berurusan dengan Node.js di mana kami ingin menghindari mencari di dalam "node_modules":
sumber
Perintah kerja sederhana:
Di atas saya menerima teks "creativecommons.org" di direktori saat ini "dspace" dan mengecualikan dirs {log, assetstore}.
Selesai
sumber
Banyak jawaban yang benar telah diberikan di sini, tetapi saya menambahkan yang ini untuk menekankan satu poin yang menyebabkan beberapa upaya tergesa-gesa untuk gagal sebelumnya:
exclude-dir
mengambil pola , bukan jalur ke direktori.Katakanlah pencarian Anda adalah:
Dan Anda perhatikan bahwa output Anda berantakan dengan hasil dari
src/other/objects-folder
. Perintah ini tidak akan memberi Anda hasil yang diinginkan:Dan Anda mungkin bertanya-tanya mengapa
exclude-dir
tidak bekerja! Untuk benar-benar mengecualikan hasil dariobjects-folder
, cukup lakukan ini:Dengan kata lain, cukup gunakan nama folder , bukan path. Jelas sekali Anda mengetahuinya.
Dari halaman manual:
sumber
Yang ini bekerja untuk saya:
sumber
sumber
Cara yang lebih sederhana adalah dengan memfilter hasil Anda menggunakan "grep -v".
grep -i needle -R * | grep -v node_modules
sumber