Làm thế nào để sử dụng regex với lệnh find?


297

Tôi có một số hình ảnh được đặt tên với chuỗi uuid1 được tạo. Ví dụ: 81394018-b84a-11e0-9d2a-001b77dc0bed.jpg. Tôi muốn tìm hiểu tất cả những hình ảnh này bằng cách sử dụng lệnh "find":

find . -regex "[a-f0-9\-]\{36\}\.jpg".

Nhưng nó không hoạt động. Có gì sai với regex? Ai đó có thể giúp tôi với cái này được không?


7
có thể thay đổi regextype. Mặc định là Biểu thức chính quy Emacs , bất kể điều đó có nghĩa là gì.
pavium

Câu trả lời:


348
find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"

Lưu ý rằng bạn cần chỉ định .*/ngay từ đầu vì findkhớp với toàn bộ đường dẫn.

Thí dụ:

susam@nifty:~/so$ find . -name "*.jpg"
./foo-111.jpg
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg

Phiên bản tìm kiếm của tôi:

$ find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0) 
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype foo -regex ".*/[a-f0-9\-]\{36\}\.jpg"
find: Unknown regular expression type `foo'; valid types are `findutils-default', `awk', `egrep', `ed', `emacs', `gnu-awk', `grep', `posix-awk', `posix-basic', `posix-egrep', `posix-extended', `posix-minimal-basic', `sed'.

4
@Tom đó là cách regex trong tìm kiếm hoạt động. Theo trang man, regex khớp với toàn bộ đường dẫn tệp, bao gồm các thư mục, có nghĩa là có một ẩn ý "^ ... $"xung quanh regex của bạn. Nó phải phù hợp với dòng kết quả WHOLE.
Manny D

2
Tôi không nghĩ rằng bạn cần có /trong .*/.*trận bằng không hoặc nhiều (gần như) bất kỳ ký tự.
Jeff

2
Đối với những người (như tôi) lần đầu tiên không đọc regex đúng cách: Lưu ý dấu gạch chéo ngược trước các ký tự regex đặc biệt, ví dụ:\{36\}
Lucas Wilson-Richter

11
Tôi gặp khó khăn khi tìm danh sách đầy đủ các loại regex (manpage không cập nhật):valid types are 'findutils-default', 'awk', ' egrep', 'ed', 'emacs', 'gnu-awk', 'grep', 'posix-awk', 'posix-basic', 'posix-egrep', 'posix -extended', 'posix-minimal-basic', 'sed'.
Noah Sussman

4
Hãy chắc chắn để đặt -regextypecờ trước khi các -regexlá cờ, nếu không nó không áp dụng!
Christopher Orr

84

Các -regexbiểu hiện tìm phù hợp với toàn bộ tên , bao gồm cả đường dẫn tương đối từ thư mục hiện hành. Đối với find .điều này luôn luôn bắt đầu với ./, sau đó bất kỳ thư mục.

Ngoài ra, đây là emacscác biểu thức chính quy, có các quy tắc thoát khác so với các biểu thức chính quy egrep thông thường.

Nếu tất cả đều trực tiếp trong thư mục hiện tại, thì

find . -regex '\./[a-f0-9\-]\{36\}\.jpg'

nên làm việc. (Tôi không thực sự chắc chắn - Tôi không thể có được sự lặp lại được tính để làm việc ở đây.) Bạn có thể chuyển sang biểu thức egrep bằng cách -regextype posix-egrep:

find . -regextype posix-egrep -regex '\./[a-f0-9\-]{36}\.jpg'

(Lưu ý rằng mọi thứ được nói ở đây là dành cho GNU find, tôi không biết gì về BSD cũng là mặc định trên Mac.)


1
Tôi đã có dấu ngoặc đơn cho nhiều chuỗi khớp trong regex của mình, vì vậy posix-egrepkiểu này hoạt động với tôi.
palswim

2
Một điều cần lưu ý, -regextypelà một tùy chọn cho GNU findchứ không phải BSD (ít nhất là không giống Mac BSD) find. Nếu tùy chọn này không có sẵn, hãy chắc chắn cài đặt GNU find. Nếu trên máy Mac thì có thể với gói bia findutils. Tìm sau đó có sẵn thông qua gfind.
DanCat

regextype posix-egrep đã làm nhiệm vụ cho tôi. Tôi nghĩ mặc định là regextype emacs.
đăng

35

Đánh giá từ các câu trả lời khác, có vẻ như đây có thể là lỗi của find.

Tuy nhiên, bạn có thể làm theo cách này thay thế:

find . * | grep -P "[a-f0-9\-]{36}\.jpg"

Bạn có thể phải điều chỉnh grep một chút và sử dụng các tùy chọn khác nhau tùy thuộc vào những gì bạn muốn nhưng nó hoạt động.


Làm việc tốt cho tôi và cung cấp một mức độ tự do tuyệt vời đối với regex.
glaucon

3
Một nhược điểm với điều này là bạn không thể tận dụng lợi thế của findcủa -prunechức năng mà sẽ bỏ qua các thư mục nhất định hoàn toàn. Thông thường điều này không thực sự quan trọng, nhưng nó đáng được đề cập.
Alexander Bird

-prune vẫn sẽ hoạt động, tôi đoán. Sẽ nguy hiểm hơn khi sử dụng -exec - nó sẽ chạy trên tất cả các tệp và không chỉ những tệp mà grep cho phép vượt qua.
tpb261

13

trên Mac OS X (BSD find) : Giống như câu trả lời được chấp nhận, .*/tiền tố là cần thiết để khớp với một đường dẫn hoàn chỉnh:

$ find -E . -regex ".*/[a-f0-9\-]{36}.jpg"

man findnói -Esử dụng hỗ trợ regex mở rộng


Có vẻ như -Ekhông có sẵn trên Ubuntu (đã được thử nghiệm trên WSL Ubuntu)
Chimpanzee hiếu chiến

2
@Clever Little Monkey - Không, câu trả lời được chấp nhận sẽ hoạt động trên Ubuntu, biến thể này dành riêng cho Mac OS X (hoặc có lẽ là một biến thể BSD khác như FreeBSD)
Stan Kurdziel

8

Cố gắng sử dụng dấu ngoặc đơn (') để tránh thoát khỏi chuỗi của chuỗi. Hãy nhớ rằng biểu thức cần khớp với toàn bộ đường dẫn, tức là cần phải trông như sau:

 find . -regex '\./[a-f0-9-]*.jpg'

Ngoài ra, dường như tìm thấy của tôi (GNU 4.4.2) chỉ biết các biểu thức chính quy cơ bản, đặc biệt không phải là cú pháp {36}. Tôi nghĩ bạn sẽ phải làm mà không có nó.


8

Cách đơn giản - bạn có thể chỉ định. * Lúc đầu vì find khớp với toàn bộ đường dẫn.

$ find . -regextype egrep -regex '.*[a-f0-9\-]{36}\.jpg$'

tìm phiên bản

$ find --version
find (GNU findutils) 4.6.0
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION 
FTS(FTS_CWDFD) CBO(level=2)

6

Bạn nên sử dụng đường dẫn thư mục tuyệt đối khi áp dụng hướng dẫn tìm với biểu thức chính quy. Trong ví dụ của bạn,

find . -regex "[a-f0-9\-]\{36\}\.jpg"

nên được đổi thành

find . -regex "./[a-f0-9\-]\{36\}\.jpg"

Trong hầu hết các hệ thống Linux, một số nguyên tắc trong biểu thức chính quy không thể được hệ thống đó nhận ra, do đó bạn phải chỉ ra rõ ràng như thế nào

find . -regextype posix-extended -regex "[a-f0-9\-]\{36\}\.jpg"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.