Làm thế nào để tôi đệ quy grep
tất cả các thư mục và thư mục con?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
không hoạt động với tôi trên Redhat Linux. Tôi nhận được một lỗi "không khớp".
Làm thế nào để tôi đệ quy grep
tất cả các thư mục và thư mục con?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
không hoạt động với tôi trên Redhat Linux. Tôi nhận được một lỗi "không khớp".
Câu trả lời:
grep -r "texthere" .
Tham số đầu tiên biểu thị biểu thức chính quy cần tìm kiếm, trong khi tham số thứ hai biểu thị thư mục cần tìm kiếm. Trong trường hợp này, .
có nghĩa là thư mục hiện tại.
Lưu ý: Điều này hoạt động với GNU grep và trên một số nền tảng như Solaris, bạn phải đặc biệt sử dụng GNU grep thay vì triển khai kế thừa. Đối với Solaris đây là ggrep
lệnh.
AIX 5.3
chẳng hạn.
Nếu bạn biết phần mở rộng hoặc mẫu của tệp bạn muốn, một phương pháp khác là sử dụng --include
tùy chọn:
grep -r --include "*.txt" texthere .
Bạn cũng có thể đề cập đến các tập tin để loại trừ với --exclude
.
Nếu bạn thường xuyên tìm kiếm thông qua mã, Ag (Trình tìm kiếm bạc) là một thay thế nhanh hơn nhiều so với grep, đó là tùy chỉnh để tìm kiếm mã. Chẳng hạn, nó được đệ quy theo mặc định và tự động bỏ qua các tệp và thư mục được liệt kê trong đó .gitignore
, vì vậy bạn không phải tiếp tục chuyển các tùy chọn loại trừ rườm rà tương tự để grep hoặc find.
=
hoạt động tốt trên Ubuntu. PS: đó được coi là một không gian được sao lưu, nhưng trình phân tích cú pháp đánh dấu SO đã thất bại.
grep
, không phải cho Ag, chỉ để bạn biết :)
--include "*.txt" --include "*.TXT"
Cũng thế:
find ./ -type f -print0 | xargs -0 grep "foo"
nhưng grep -r
là một câu trả lời tốt hơn
find . -type f -exec grep "foo" '{}' \;
hoạt động tốt ở những nơi được hỗ trợ.
find ./ -type f -print0 | xargs -0 grep "foo"
Bây giờ tôi luôn sử dụng (ngay cả trên Windows với GoW - Gnu trên Windows ):
grep --include="*.xxx" -nRHI "my Text to grep" *
Điều đó bao gồm các tùy chọn sau:
--include=PATTERN
Recurse trong thư mục chỉ tìm kiếm tập tin phù hợp
PATTERN
.
-n, --line-number
Tiền tố mỗi dòng đầu ra với số dòng trong tệp đầu vào của nó.
(Lưu ý: phuclv thêm trong các ý kiến đó -n
làm giảm hiệu suất rất nhiều vì vậy , vì vậy bạn có thể muốn bỏ qua tùy chọn đó)
-R, -r, --recursive
Đọc tất cả các tệp trong mỗi thư mục, đệ quy; Điều này tương đương với
-d recurse
tùy chọn.
-H, --with-filename
In tên tệp cho mỗi trận đấu.
-I
Xử lý một tệp nhị phân như thể nó không chứa dữ liệu phù hợp;
Điều này tương đương với--binary-files=without-match
tùy chọn.
Và tôi có thể thêm ' i
' ( -nRHIi
), nếu tôi muốn kết quả không phân biệt chữ hoa chữ thường.
Tôi co thể lây:
/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
tùy chọn) cho các thư mục.
*
hoặc .
là một mô hình toàn cầu (được giải thích bởi trình bao): unix.stackexchange.com/a/64695/7490 . ' .
' cũng sẽ chọn các thư mục dotfiles hoặc dot (như .git/
)
grep -rnI
nhưng sau đó tôi đã học được rằng -n
làm giảm hiệu suất rất nhiều vì vậy tôi chỉ sử dụng nó khi thực sự cần thiết và thông thường tôi sẽ sử dụng-rI
Trong các hệ thống POSIX, bạn không tìm thấy -r
tham số cho grep
và bạn grep -rn "stuff" .
sẽ không chạy, nhưng nếu bạn sử dụng find
lệnh thì nó sẽ:
find . -type f -exec grep -n "stuff" {} \; -print
Đồng ý bởi Solaris
và HP-UX
.
-exec
tùy chọn - biểu tượng {}
là một tham chiếu đến tên tệp hiện được tìm thấy bởi find
công cụ (nghĩa là làm một cái gì đó với tên tệp mà chúng ta đã tìm thấy), cũng -exec
nên kết thúc tùy chọn bằng ;
ký hiệu (để đánh dấu kết thúc của lệnh exec), nhưng vì đây là tất cả chạy trong một vỏ mà biểu tượng nên được thoát .. và cuối cùng -print
tùy chọn cho phép find
công cụ in ra tên tệp tìm thấy trên màn hình.
**
Sử dụng grep -r
công việc, nhưng nó có thể quá mức, đặc biệt là trong các thư mục lớn.
Để sử dụng thực tế hơn, đây là cú pháp sử dụng cú pháp toàn cầu ( **
):
grep "texthere" **/*.txt
mà chỉ greps các tập tin cụ thể với mẫu đã chọn mẫu. Nó hoạt động cho các shell được hỗ trợ như Bash +4 hoặc zsh .
Để kích hoạt tính năng này, hãy chạy : shopt -s globstar
.
Xem thêm: Làm cách nào để tìm tất cả các tệp chứa văn bản cụ thể trên Linux?
git grep
Đối với các dự án dưới sự kiểm soát phiên bản Git, hãy sử dụng:
git grep "pattern"
đó là nhanh hơn nhiều.
ripgrep
Đối với các dự án lớn hơn, công cụ grepping nhanh nhất là ripgrep
các tệp greps theo cách đệ quy theo mặc định:
rg "pattern" .
Nó được xây dựng trên đỉnh công cụ regex của Rust , sử dụng automata hữu hạn, SIMD và tối ưu hóa theo nghĩa đen tích cực để giúp tìm kiếm rất nhanh. Kiểm tra phân tích chi tiết tại đây .
Để tìm tên files
với path
đệ quy có chứa các đặc biệt string
sử dụng dưới lệnh cho UNIX
:
find . | xargs grep "searched-string"
cho Linux
:
grep -r "searched-string" .
tìm một tập tin trên UNIX
máy chủ
find . -type f -name file_name
tìm một tập tin trên máy chủ LINUX
find . -name file_name
Nếu bạn chỉ muốn theo dõi các thư mục thực tế, và không liên kết tượng trưng,
grep -r "thingToBeFound" directory
Nếu bạn muốn theo các liên kết tượng trưng cũng như các thư mục thực tế (hãy cẩn thận với đệ quy vô hạn),
grep -R "thing to be found" directory
Vì bạn đang cố gắng grep đệ quy, các tùy chọn sau cũng có thể hữu ích cho bạn:
-H: outputs the filename with the line
-n: outputs the line number in the file
Vì vậy, nếu bạn muốn tìm tất cả các tệp chứa Darth Vader trong thư mục hiện tại hoặc bất kỳ thư mục con nào và chụp tên tệp và số dòng, nhưng không muốn đệ quy theo các liên kết tượng trưng, lệnh sẽ là
grep -rnH "Darth Vader" .
Nếu bạn muốn tìm tất cả các đề cập đến từ mèo trong thư mục
/home/adam/Desktop/TomAndJerry
và bạn hiện đang ở trong thư mục
/home/adam/Desktop/WorldDominationPlot
và bạn muốn chụp tên tệp nhưng không phải là số dòng của bất kỳ trường hợp nào của chuỗi "mèo" và bạn muốn đệ quy theo các liên kết tượng trưng nếu tìm thấy chúng, bạn có thể chạy một trong các cách sau
grep -RH "cats" ../TomAndJerry #relative directory
grep -RH "cats" /home/adam/Desktop/TomAndJerry #absolute directory
Nguồn:
chạy "grep - trợ giúp"
Giới thiệu ngắn về các liên kết tượng trưng, cho bất kỳ ai đọc câu trả lời này và bối rối bởi tài liệu tham khảo của tôi cho họ: https://www.nixtutor.com/freebsd/under Hiểu-symbolic-links /
ag là cách yêu thích của tôi để làm điều này ngay bây giờ github.com/ggreer/the_silver_searcher . Về cơ bản nó giống như ack nhưng với một vài tối ưu hóa hơn.
Đây là một điểm chuẩn ngắn. Tôi xóa bộ nhớ cache trước mỗi bài kiểm tra (cf https://askubfox.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
Điều này sẽ làm việc:
grep -R "texthere" *
Nếu bạn đang tìm kiếm một nội dung cụ thể trong tất cả các tệp từ cấu trúc thư mục, bạn có thể sử dụng find
vì nó rõ ràng hơn những gì bạn đang làm:
find -type f -exec grep -l "texthere" {} +
Lưu ý rằng -l
(chữ thường của L) hiển thị tên của tệp chứa văn bản. Hủy bỏ nó nếu bạn muốn in trận đấu chính nó. Hoặc sử dụng -H
để có được các tập tin cùng với trận đấu. Tất cả cùng nhau, các lựa chọn thay thế khác là:
find -type f -exec grep -Hn "texthere" {} +
Trường hợp -n
in số dòng.
find
giải pháp cho cả hai tránh sử dụng không cần thiết của xargs
và sử dụng +
thay vì \;
với -exec
, do đó tránh được tấn của quá trình ra mắt không cần thiết. :-)
Đây là cái đã hoạt động cho trường hợp của tôi trên máy hiện tại của tôi (git bash trên windows 7):
find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
Tôi luôn quên -print0 và -0 cho các đường dẫn có khoảng trắng.
EDIT: Công cụ ưa thích của tôi bây giờ thay vì ripgrep: https://github.com/BurntSushi/ripgrep/release . Nó thực sự nhanh và có mặc định tốt hơn (như đệ quy theo mặc định). Ví dụ giống như câu trả lời ban đầu của tôi nhưng sử dụng ripgrep:rg -g "*.cs" "content pattern"
grep -r "texthere" .
(thời gian thông báo ở cuối)
(^ tín dụng: https://stackoverflow.com/a/1987928/1438029 )
Làm rõ:
grep -r "texthere" /
(grep đệ quy tất cả các thư mục và thư mục con)
grep -r "texthere" .
(đệ quy grep các thư mục và thư mục con này)
grep [options] PATTERN [FILE...]
[tùy chọn]
-R, -r, --recursive
Đọc tất cả các tập tin dưới mỗi thư mục, đệ quy.
Điều này tương đương với
-d recurse
hoặc--directories=recurse
tùy chọn.
$ grep --help
$ grep --help |grep recursive
-r, --recursive like --directories=recurse
-R, --dereference-recursive
ack
( http://beyondgrep.com/ )
Năm 2018, bạn muốn sử dụng ripgrep
hoặc the-silver-searcher
vì chúng nhanh hơn các lựa chọn thay thế.
Đây là một thư mục với 336 thư mục con cấp đầu tiên:
% 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
Trên OSX, cài đặt này ripgrep
: brew install ripgrep
. Cài đặt này silver-searcher
: brew install the_silver_searcher
.
rg
có một lợi thế đáng kể so với việc gắn kết một lệnh grep đệ quy từ đầu. Sử dụng rg
: rg foo
. Sử dụng các công cụ unix : find . | xargs grep foo
. Và nếu bất kỳ tệp nào của bạn có trích dẫn trong đó, bạn cần sử dụng find . -print0 | xargs -0 grep foo
. Bạn sẽ nhớ rằng nếu bạn sử dụng điều này một vài lần một năm?
find . -type f -exec grep 'regex' {} +
điều thực sự dễ nhớ nếu bạn sử dụng những công cụ này với bất kỳ sự thường xuyên nào. Nhưng có lẽ bạn vẫn nên chạy ctags
hoặc etags
trên cây nguồn của mình nếu bạn cần tìm công cụ thường xuyên.
Trong Máy chủ IBM AIX của tôi (phiên bản HĐH: AIX 5.2), sử dụng:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
điều này sẽ in ra đường dẫn / tên tệp và số dòng tương đối trong tệp như:
./inc/xxxx_x.h
2865: / ** Mô tả: chuỗiYouWannaFind * /
dù sao, nó hoạt động với tôi :)
Dưới đây là lệnh để tìm kiếm String
đệ quy trên Unix
vàLinux
môi trường.
cho UNIX
lệnh là:
find . -name "string to be searched" -exec grep "text" "{}" \;
cho Linux
lệnh là:
grep -r "string to be searched" .
Đối với một danh sách các cờ có sẵn:
grep --help
Trả về tất cả các kết quả khớp cho văn bản regrec trong thư mục hiện tại, với số dòng tương ứng:
grep -rn "texthere" .
Trả về tất cả các kết quả khớp cho texthere , bắt đầu từ thư mục gốc, với số dòng tương ứng và trường hợp bỏ qua:
grep -rni "texthere" /
cờ được sử dụng ở đây:
-r
đệ quy -n
in số dòng với đầu ra -i
bỏ qua trường hợpTôi đoán đây là những gì bạn đang cố viết
grep myText $(find .)
và điều này có thể là một cái gì đó hữu ích nếu bạn muốn tìm các tập tin grep hit
grep myText $(find .) | cut -d : -f 1 | sort | uniq
Lưu ý rằng find . -type f | xargs grep whatever
các loại giải pháp sẽ chạy vào lỗi "Danh sách đối số dài" khi có quá nhiều tệp phù hợp với tìm kiếm.
Đặt cược tốt nhất là grep -r
nhưng nếu điều đó không có sẵn, find . -type f -exec grep -H whatever {} \;
thay vào đó hãy sử dụng .
xargs
đặc biệt là một cách giải quyết cho vấn đề "Danh sách đối số quá dài".
find . -type f | xargs -L 100 grep whatever
xargs
được chuẩn hóa để loại bỏ hành vi này. " xargs
Tiện ích sẽ giới hạn độ dài dòng lệnh sao cho khi dòng lệnh được gọi, đối số kết hợp và danh sách môi trường ... sẽ không vượt quá {ARG_MAX} -2048 byte."
Đây là một hàm đệ quy (được kiểm tra nhẹ với hàm bash và sh) đi qua tất cả các thư mục con của một thư mục đã cho ($ 1) và sử dụng grep
các tìm kiếm cho chuỗi đã cho ($ 3) trong các tệp đã cho ($ 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"
Chạy nó và một ví dụ đầu ra:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename