Bagaimana saya secara rekursif grep
semua direktori dan subdirektori?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
tidak bekerja untuk saya di Redhat Linux. Saya mendapatkan kesalahan "tidak cocok".
Bagaimana saya secara rekursif grep
semua direktori dan subdirektori?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
tidak bekerja untuk saya di Redhat Linux. Saya mendapatkan kesalahan "tidak cocok".
Jawaban:
grep -r "texthere" .
Parameter pertama mewakili ekspresi reguler untuk dicari, sedangkan yang kedua mewakili direktori yang harus dicari. Dalam hal ini, .
berarti direktori saat ini.
Catatan: Ini berfungsi untuk grep GNU, dan pada beberapa platform seperti Solaris Anda harus secara khusus menggunakan grep GNU sebagai lawan implementasi legacy. Untuk Solaris ini adalah ggrep
perintahnya.
AIX 5.3
misalnya.
Jika Anda tahu ekstensi atau pola file yang Anda inginkan, metode lain adalah menggunakan --include
opsi:
grep -r --include "*.txt" texthere .
Anda juga dapat menyebutkan file yang akan dikecualikan --exclude
.
Jika Anda sering mencari melalui kode, Ag (The Silver Searcher) adalah alternatif yang jauh lebih cepat daripada grep, yang disesuaikan untuk mencari kode. Sebagai contoh, ini bersifat rekursif secara default dan secara otomatis mengabaikan file dan direktori yang terdaftar .gitignore
, sehingga Anda tidak harus terus melewati opsi pengecualian yang rumit untuk diambil atau ditemukan.
=
berfungsi dengan baik di Ubuntu. PS: itu seharusnya adalah ruang backticked, tetapi parser penurunan harga SO gagal.
grep
, bukan untuk Ag, asal kau tahu :)
--include "*.txt" --include "*.TXT"
Juga:
find ./ -type f -print0 | xargs -0 grep "foo"
tetapi grep -r
merupakan jawaban yang lebih baik.
find . -type f -exec grep "foo" '{}' \;
berfungsi dengan baik jika didukung.
find ./ -type f -print0 | xargs -0 grep "foo"
Sekarang saya selalu menggunakan (bahkan di Windows dengan GoW - Gnu di Windows ):
grep --include="*.xxx" -nRHI "my Text to grep" *
Itu termasuk opsi berikut:
--include=PATTERN
Berulang dalam direktori hanya mencari pencocokan file
PATTERN
.
-n, --line-number
Awali setiap baris output dengan nomor baris di dalam file inputnya.
(Catatan: phuclv menambahkan komentar yang sangat -n
mengurangi kinerja , jadi Anda mungkin ingin melewatkan opsi itu)
-R, -r, --recursive
Baca semua file di bawah setiap direktori, secara rekursif; ini setara dengan
-d recurse
opsi.
-H, --with-filename
Cetak nama file untuk setiap kecocokan.
-I
Memproses file biner seolah-olah tidak mengandung data yang cocok;
ini setara dengan--binary-files=without-match
opsi.
Dan saya dapat menambahkan ' i
' ( -nRHIi
), jika saya ingin hasil case-insensitive.
Saya bisa mendapatkan:
/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43: 'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21: $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32: $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20: protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170: * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176: return $this->hidden;
...
-R
opsi) ke folder.
*
atau .
merupakan pola glob (ditafsirkan oleh shell): unix.stackexchange.com/a/64695/7490 . ' .
' akan memilih dotfile atau folder dot juga (seperti .git/
)
grep -rnI
tetapi kemudian saya belajar bahwa banyak -n
menurunkan kinerja jadi saya hanya menggunakannya ketika benar-benar diperlukan dan biasanya saya akan menggunakan-rI
Dalam sistem POSIX, Anda tidak menemukan -r
parameter untuk grep
dan Anda grep -rn "stuff" .
tidak akan berjalan, tetapi jika Anda menggunakan find
perintah itu akan:
find . -type f -exec grep -n "stuff" {} \; -print
Disetujui oleh Solaris
dan HP-UX
.
-exec
opsi - simbol {}
adalah referensi ke nama file yang saat ini ditemukan oleh find
alat (yaitu melakukan sesuatu dengan nama file yang kami temukan), juga -exec
opsi harus diakhiri dengan ;
simbol (untuk menandai akhir dari perintah exec), tetapi karena ini semua berjalan di shell bahwa simbol harus melarikan diri .. dan akhirnya -print
opsi memungkinkan find
alat untuk mencetak nama file yang ditemukan di layar.
**
Menggunakan grep -r
karya, tetapi mungkin berlebihan, terutama di folder besar.
Untuk penggunaan yang lebih praktis, ini adalah sintaks yang menggunakan sintaks globbing ( **
):
grep "texthere" **/*.txt
yang hanya menangkap file tertentu dengan pola pola yang dipilih. Ia bekerja untuk cangkang yang didukung seperti Bash +4 atau zsh .
Untuk mengaktifkan fitur ini, jalankan: shopt -s globstar
.
Lihat juga: Bagaimana cara menemukan semua file yang mengandung teks tertentu di Linux?
git grep
Untuk proyek-proyek di bawah kendali versi Git, gunakan:
git grep "pattern"
yang jauh lebih cepat.
ripgrep
Untuk proyek yang lebih besar, alat grepping tercepat adalah ripgrep
greps file secara rekursif secara default:
rg "pattern" .
Itu dibangun di atas mesin regex Rust yang menggunakan automata terbatas, SIMD dan optimasi literal agresif untuk membuat pencarian sangat cepat. Periksa analisis terperinci di sini .
Untuk menemukan nama files
dengan path
secara rekursif yang string
menggunakan perintah khusus di bawah ini untuk UNIX
:
find . | xargs grep "searched-string"
untuk Linux
:
grep -r "searched-string" .
cari file di UNIX
server
find . -type f -name file_name
cari file di server LINUX
find . -name file_name
Jika Anda hanya ingin mengikuti direktori aktual, dan bukan tautan simbolik,
grep -r "thingToBeFound" directory
Jika Anda ingin mengikuti tautan simbolik serta direktori aktual (berhati-hatilah terhadap rekursi tak terbatas),
grep -R "thing to be found" directory
Karena Anda mencoba untuk menerjang secara rekursif, opsi berikut ini mungkin juga berguna bagi Anda:
-H: outputs the filename with the line
-n: outputs the line number in the file
Jadi jika Anda ingin menemukan semua file yang mengandung Darth Vader di direktori saat ini atau subdirektori apa pun dan menangkap nama file dan nomor baris, tetapi tidak ingin rekursi mengikuti tautan simbolik, perintahnya adalah
grep -rnH "Darth Vader" .
Jika Anda ingin menemukan semua sebutan kata cat di direktori
/home/adam/Desktop/TomAndJerry
dan Anda saat ini berada di direktori
/home/adam/Desktop/WorldDominationPlot
dan Anda ingin mengambil nama file tetapi bukan nomor baris dari sembarang string "kucing", dan Anda ingin rekursi mengikuti tautan simbolis jika menemukannya, Anda bisa menjalankan salah satu dari berikut ini
grep -RH "cats" ../TomAndJerry #relative directory
grep -RH "cats" /home/adam/Desktop/TomAndJerry #absolute directory
Sumber:
menjalankan "grep --help"
Pengantar singkat untuk tautan simbolik, bagi siapa pun yang membaca jawaban ini dan bingung dengan referensi saya kepada mereka: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
ag adalah cara favorit saya untuk melakukan ini sekarang github.com/ggreer/the_silver_searcher . Ini pada dasarnya hal yang sama dengan ACK tetapi dengan beberapa optimasi lagi.
Inilah patokan singkat. Saya menghapus cache sebelum setiap tes (lih. Https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache )
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
Ini seharusnya bekerja:
grep -R "texthere" *
Jika Anda mencari konten tertentu di semua file dari struktur direktori, Anda dapat menggunakannya find
karena lebih jelas apa yang Anda lakukan:
find -type f -exec grep -l "texthere" {} +
Perhatikan bahwa -l
(huruf kecil L) menunjukkan nama file yang berisi teks. Hapus itu jika Anda ingin mencetak pertandingan itu sendiri. Atau gunakan -H
untuk mendapatkan file bersama dengan pertandingan. Secara keseluruhan, alternatif lain adalah:
find -type f -exec grep -Hn "texthere" {} +
Di mana -n
mencetak nomor baris.
find
solusi untuk menghindari penggunaan yang tidak perlu xargs
dan penggunaan +
alih-alih \;
dengan -exec
, dengan demikian menghindari berton-ton proses peluncuran yang tidak perlu. :-)
Ini adalah yang bekerja untuk kasus saya di mesin saya saat ini (git bash di windows 7):
find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
Saya selalu lupa -print0 dan -0 untuk path dengan spasi.
Sunting: Alat pilihan saya sekarang bukan ripgrep: https://github.com/BurntSushi/ripgrep/releases . Ini sangat cepat dan memiliki standar yang lebih baik (seperti rekursif secara default). Contoh yang sama dengan jawaban asli saya tetapi menggunakan ripgrep:rg -g "*.cs" "content pattern"
grep -r "texthere" .
(periode pemberitahuan di akhir)
(^ kredit: https://stackoverflow.com/a/1987928/1438029 )
Klarifikasi:
grep -r "texthere" /
(grep semua direktori dan subdirektori secara rekursif )
grep -r "texthere" .
(rekursif grep ini direktori dan subdirektori)
grep [options] PATTERN [FILE...]
[pilihan]
-R, -r, --recursive
Baca semua file di bawah setiap direktori, secara rekursif.
Ini sama dengan opsi
-d recurse
atau--directories=recurse
.
$ grep --help
$ grep --help |grep recursive
-r, --recursive like --directories=recurse
-R, --dereference-recursive
ack
( http://beyondgrep.com/ )
Pada 2018, Anda ingin menggunakan ripgrep
atau the-silver-searcher
karena mereka jauh lebih cepat daripada alternatifnya.
Berikut adalah direktori dengan 336 subdirektori tingkat pertama:
% find . -maxdepth 1 -type d | wc -l
336
% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py' 1.24s user 2.23s system 283% cpu 1.222 total
% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$' 2.71s user 1.55s system 116% cpu 3.651 total
% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py' 1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs 6.65s user 0.49s system 32% cpu 22.164 total
Pada OSX, ini akan menginstal ripgrep
: brew install ripgrep
. Ini akan menginstal silver-searcher
: brew install the_silver_searcher
.
rg
memiliki keunggulan yang cukup besar dalam membuat perintah grep rekursif dari awal. Menggunakan rg
: rg foo
. Menggunakan alat unix: find . | xargs grep foo
. Dan jika ada file Anda yang memiliki kutipan di dalamnya, Anda perlu menggunakannya find . -print0 | xargs -0 grep foo
. Apakah Anda akan ingat bahwa jika Anda menggunakannya beberapa kali dalam setahun?
find . -type f -exec grep 'regex' {} +
yang memang mudah diingat jika Anda menggunakan alat ini dengan teratur. Tetapi mungkin Anda harus menjalankan ctags
atau etags
pada pohon sumber Anda jika Anda perlu menemukan barang-barang sering.
Di IBM AIX Server saya (versi OS: AIX 5.2), gunakan:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
ini akan mencetak path / nama file dan nomor baris relatif dalam file seperti:
./inc/xxxx_x.h
2865: / ** Keterangan: stringYouWannaFind * /
bagaimanapun, ini bekerja untuk saya :)
Di bawah ini adalah perintah untuk pencarian String
di lingkungan Unix
dan rekursif Linux
.
untuk UNIX
perintah adalah:
find . -name "string to be searched" -exec grep "text" "{}" \;
untuk Linux
perintah adalah:
grep -r "string to be searched" .
Untuk daftar bendera yang tersedia:
grep --help
Mengembalikan semua kecocokan untuk teks regexp di direktori saat ini, dengan nomor baris yang sesuai:
grep -rn "texthere" .
Mengembalikan semua kecocokan untuk texthere , mulai dari direktori root, dengan nomor baris yang sesuai dan mengabaikan case:
grep -rni "texthere" /
bendera yang digunakan di sini:
-r
rekursif -n
cetak nomor baris dengan output -i
abaikan caseSaya kira inilah yang ingin Anda tulis
grep myText $(find .)
dan ini mungkin sesuatu yang bermanfaat jika Anda ingin menemukan file grep hit
grep myText $(find .) | cut -d : -f 1 | sort | uniq
Melemparkan dua sen saya di sini. Seperti yang telah disebutkan orang lain grep -r tidak bekerja di setiap platform. Ini mungkin terdengar konyol tapi saya selalu menggunakan git.
git grep "texthere"
Bahkan jika direktori tersebut tidak dipentaskan, saya hanya menjalankannya dan menggunakan git grep.
Perhatikan bahwa find . -type f | xargs grep whatever
berbagai jenis solusi akan mengalami kesalahan "Daftar argumen sampai panjang" ketika ada terlalu banyak file yang cocok dengan find.
Taruhan terbaik adalah grep -r
tetapi jika itu tidak tersedia, gunakan find . -type f -exec grep -H whatever {} \;
saja.
xargs
secara khusus merupakan solusi untuk masalah "Daftar argumen terlalu panjang".
find . -type f | xargs -L 100 grep whatever
xargs
distandarisasi untuk memiliki perilaku ini di luar kotak. " xargs
Utilitas akan membatasi panjang baris perintah sehingga ketika baris perintah dipanggil, argumen gabungan dan daftar lingkungan ... tidak boleh melebihi {ARG_MAX} -2048 byte."
Berikut ini adalah fungsi rekursif (diuji ringan dengan bash dan sh) yang melintasi semua subfolder dari folder tertentu ($ 1) dan menggunakan grep
pencarian untuk string yang diberikan ($ 3) dalam file yang diberikan ($ 2):
$ cat script.sh
#!/bin/sh
cd "$1"
loop () {
for i in *
do
if [ -d "$i" ]
then
# echo entering "$i"
cd "$i"
loop "$1" "$2"
fi
done
if [ -f "$1" ]
then
grep -l "$2" "$PWD/$1"
fi
cd ..
}
loop "$2" "$3"
Menjalankannya dan contoh output:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename