Saya mencari string foo=
dalam file teks di pohon direktori. Ada di mesin Linux yang umum, saya punya bash shell:
grep -ircl "foo=" *
Dalam direktori juga banyak file biner yang cocok dengan "foo =". Karena hasil ini tidak relevan dan memperlambat pencarian, saya ingin grep melewati pencarian file-file ini (kebanyakan gambar JPEG dan PNG). Bagaimana saya melakukannya?
Saya tahu ada opsi --exclude=PATTERN
dan --include=PATTERN
, tapi apa format pola? Halaman manual grep mengatakan:
--include=PATTERN Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN Recurse in directories skip file matching PATTERN.
Pencarian di grep meliputi , grep termasuk mengecualikan , grep mengecualikan dan varian tidak menemukan sesuatu yang relevan
Jika ada cara yang lebih baik untuk menangkap hanya dalam file-file tertentu, saya siap untuk itu; memindahkan file yang menyinggung bukanlah pilihan. Saya tidak dapat mencari hanya direktori tertentu (struktur direktori berantakan, dengan semuanya ada di mana-mana). Juga, saya tidak dapat menginstal apa-apa, jadi saya harus melakukan dengan alat umum (seperti grep atau disarankan find ).
--exclude-dir=.svn
, jadi grep tidak masuk ke mereka sama sekaligrep -r --exclude-dir=var "pattern" .
Jawaban:
Gunakan sintaks globbing shell:
Sintaks untuk
--exclude
identik.Perhatikan bahwa bintang tersebut lolos dengan garis miring terbalik untuk mencegahnya diperluas oleh shell (mengutipnya, seperti
--include="*.{cpp,h}"
, akan bekerja dengan baik juga). Kalau tidak, jika Anda memiliki file di direktori kerja saat ini yang cocok dengan pola, baris perintah akan meluas ke sesuatu sepertigrep pattern -r --include=foo.cpp --include=bar.h rootdir
, yang hanya akan mencari file bernamafoo.cpp
danbar.h
, yang kemungkinan besar tidak seperti yang Anda inginkan.sumber
grep pattern -r --include="*.{cpp,h}" rootdir
grep pattern -r --include=foo.cpp --include=bar.h rootdir
, yang hanya akan mencari file bernamafoo.cpp
ataubar.h
. Jika Anda tidak memiliki file yang cocok dengan glob di direktori saat ini, maka shell meneruskan glob untuk grep, yang menafsirkannya dengan benar.--exclude-dir
opsi perlu . Aturan yang sama berlaku. Hanya nama file direktori yang cocok, bukan jalan.--include
sepertinya tidak berhasil setelahnya--exclude
. Saya kira tidak masuk akal untuk mencoba, kecuali bahwa saya harus memahamialias
daftar panjang--exclude
dan--exclude-dir
, yang saya gunakan untuk mencari kode, mengabaikan perpustakaan dan bertukar file dan hal-hal. Aku akan berharap bahwagrep -r --exclude='*.foo' --include='*.bar'
akan bekerja, sehingga saya bisa membatasi sayaalias
untuk--include='*.bar'
hanya, tetapi tampaknya mengabaikan--include
dan termasuk segala sesuatu yang bukan file .foo. Menukar urutan--include
dan--exclude
bekerja, tetapi sayangnya, itu tidak membantu sayaalias
.PATTERN
. Setengah jam saya tidak dapat menemukan penjelasan apa pun yang mereka tunggu di sanaJika Anda hanya ingin melewatkan file biner, saya sarankan Anda melihat opsi
-I
(huruf besar i). Itu mengabaikan file biner. Saya secara teratur menggunakan perintah berikut:Itu mencari secara rekursif, mengabaikan file biner, dan tidak melihat ke dalam folder tersembunyi Subversion, untuk pola apa pun yang saya inginkan. Saya memilikinya alias "grepsvn" di kotak saya di tempat kerja.
sumber
--exclude-dir
tidak tersedia di mana-mana. kotak RH saya bekerja dengan GNU grep 2.5.1 tidak memilikinya.--exclude-dir
tidak tersedia? Dalam semua upaya saya,--exclude
tampaknya tidak sesuai dengan tagihan.--exclude-dir="\.git"
. :-)Silakan lihat ack , yang dirancang untuk situasi ini. Contoh Anda dari
dilakukan dengan ack as
karena ack tidak pernah melihat file biner secara default, dan -r diaktifkan secara default. Dan jika Anda hanya menginginkan file CPP dan H, lakukan saja
sumber
apt-get
di Ubuntu :)awk
grep 2.5.3 memperkenalkan parameter --exclude-dir yang akan bekerja seperti yang Anda inginkan.
Anda juga dapat mengatur variabel lingkungan: GREP_OPTIONS = "- exclude-dir = .svn"
Saya akan memilih Andy kedua untuk ack , itu yang terbaik.
sumber
Saya menemukan ini setelah waktu yang lama, Anda dapat menambahkan beberapa menyertakan dan mengecualikan seperti:
sumber
Perintah yang disarankan:
secara konseptual salah, karena --exclude bekerja pada nama dasar. Dengan kata lain, ini hanya akan melewatkan .svn di direktori saat ini.
sumber
Di grep 2.5.1 Anda harus menambahkan baris ini ke profil ~ / .bashrc atau ~ / .bash
sumber
Saya menemukan kadang-kadang grepping keluaran grep sangat membantu:
Padahal, itu tidak benar-benar menghentikannya dari mencari file biner.
sumber
grep -I
untuk melewati file biner.Jika Anda tidak suka menggunakan
find
, saya suka-prune
fiturnya:Pada baris pertama, Anda menentukan direktori yang ingin Anda cari.
.
(direktori saat ini) adalah jalur yang valid, misalnya.Pada tanggal 2 dan garis-3, penggunaan
"*.png"
,"*.gif"
,"*.jpg"
, dan sebagainya. Gunakan sebanyak ini-o -name "..." -prune
konstruksi sebanyak yang Anda punya pola.Pada baris ke-4, Anda memerlukan yang lain
-o
(ini menentukan "atau" untukfind
), pola yang Anda inginkan, dan Anda perlu a-print
atau-print0
di akhir. Jika Anda hanya ingin "segala sesuatu yang lain" yang tetap setelah pemangkasan*.gif
,*.png
dll gambar, maka penggunaan-o -print0
dan Anda selesai dengan garis-4.Akhirnya, pada baris ke-5 adalah pipa
xargs
yang mengambil masing-masing file yang dihasilkan dan menyimpannya dalam suatu variabelFILENAME
. Kemudian melewatigrep
satu-IR
bendera, yang"pattern"
, dan kemudianFILENAME
diperluas olehxargs
untuk menjadi yang daftar nama file ditemukan olehfind
.Untuk pertanyaan khusus Anda, pernyataan itu mungkin terlihat seperti:
sumber
-false
segera setelah masing-masing-prune
jadi lupa untuk menggunakan-print0
atau semacamexec
perintah tidak akan benar-benar mencetak file yang ingin Anda kecualikan:-name "*.png" -prune -false -o name "*.gif -prune -false
...Pada CentOS 6.6 / Grep 2.6.3, saya harus menggunakannya seperti ini:
Perhatikan kurangnya tanda-tanda sama "=" (jika tidak
--include
,--exclude
,include-dir
dan--exclude-dir
diabaikan)sumber
git grep
Gunakan
git grep
yang dioptimalkan untuk kinerja dan bertujuan untuk mencari melalui file-file tertentu.Secara default ia mengabaikan file biner dan itu menghormati Anda
.gitignore
. Jika Anda tidak bekerja dengan struktur Git, Anda masih bisa menggunakannya dengan melewati--no-index
.Sintaks contoh:
Untuk lebih banyak contoh, lihat:
sumber
Saya seorang dilettante, memang begitu, tapi begini tampilannya ~ / .bash_profile saya:
Perhatikan bahwa untuk mengecualikan dua direktori, saya harus menggunakan --exclude-dir dua kali.
sumber
Coba yang ini:
Ditemukan di sini: http://www.unix.com/shell-programming-scripting/42573-search-files-excluding-binary-files.html
sumber
Jika Anda mencari secara non-rekursif, Anda dapat menggunakan pola glop untuk mencocokkan nama file.
termasuk html dan txt. Hanya mencari di direktori saat ini.
Untuk mencari di subdirektori:
Dalam subdirektori:
sumber
ripgrep
Ini adalah salah satu alat tercepat yang dirancang untuk mencari direktori Anda saat ini secara rekursif. Itu ditulis dalam Rust , dibangun di atas mesin regex Rust untuk efisiensi maksimum. Periksa analisis terperinci di sini .
Jadi Anda bisa menjalankan:
Ini menghormati Anda
.gitignore
dan secara otomatis melewati file / direktori tersembunyi dan file biner.Anda masih dapat menyesuaikan menyertakan atau mengecualikan file dan direktori menggunakan
-g
/--glob
. Aturan gumpal cocok dengan.gitignore
gumpalan. Periksaman rg
bantuan.Untuk contoh lainnya, lihat: Bagaimana cara mengecualikan beberapa file yang tidak cocok dengan ekstensi tertentu dengan grep?
Di macOS, Anda dapat menginstal via
brew install ripgrep
.sumber
find dan xargs adalah temanmu. Gunakan mereka untuk memfilter daftar file daripada grep --exclude
Coba sesuatu seperti
Keuntungan dari membiasakan diri dengan ini, adalah dapat diperluas ke kasus penggunaan lain, misalnya untuk menghitung baris di semua file non-png:
Untuk menghapus semua file non-png:
dll.
Seperti yang ditunjukkan dalam komentar, jika beberapa file memiliki spasi dalam namanya, gunakan
-print0
danxargs -0
sebagai gantinya.sumber
skrip tersebut tidak menyelesaikan semua masalah ... Coba ini lebih baik:
skrip ini sangat baik, karena menggunakan ekspresi reguler "nyata" untuk menghindari direktori dari pencarian. cukup pisahkan nama folder atau file dengan "\ |" pada grep -v
bersenang senang lah! ditemukan di shell linux saya! XD
sumber
Lihat @ yang ini.
sumber
The
--binary-files=without-match
pilihan untuk GNUgrep
mendapatkannya untuk melewati file biner. (Setara dengan-I
sakelar yang disebutkan di tempat lain.)(Ini mungkin memerlukan versi terbaru
grep
; 2.5.3 memilikinya, setidaknya.)sumber
cocok untuk file .alias tcsh:
Butuh waktu beberapa saat untuk mengetahui bahwa bagian {mm, m, h, cc, c} TIDAK boleh berada di dalam tanda kutip. ~ Keith
sumber
Untuk mengabaikan semua hasil biner dari grep
Bagian awk akan menyaring semua file yang cocok dengan file Biner
sumber
Coba ini:
--F
" di bawah currdir .. (atau tautkan folder lain di sana diganti namanya menjadi "--F
" yaitudouble-minus-F
.#> grep -i --exclude-dir="\-\-F" "pattern" *
sumber