Tìm tất cả các tệp có tên chứa chuỗi


177

Tôi đã tìm kiếm một lệnh sẽ trả về các tệp từ thư mục hiện tại có chứa một chuỗi trong tên tệp. Tôi đã thấy locatefindcác lệnh có thể tìm thấy các tập tin bắt đầu bằng một cái gì đó first_word*hoặc kết thúc bằng một cái gì đó *.jpg.

Làm cách nào tôi có thể trả về danh sách các tệp chứa chuỗi trong tên tệp?

Ví dụ, nếu 2012-06-04-touch-multiple-files-in-linux.markdownlà một tập tin trong thư mục hiện tại.

Làm thế nào tôi có thể trả lại tập tin này và những người khác có chứa chuỗi touch? Sử dụng một lệnh nhưfind '/touch/'


Câu hỏi khó hiểu. Bạn có muốn tìm các tệp chứa một chuỗi hoặc các tệp có tên chứa chuỗi đã nói không? câu hỏi đầu tiên được trả lời với man grep, câu hỏi thứ hai với man find. Tại sao bạn google thay vì sử dụng người đàn ông, tôi không biết.
chỉ ai đó

1
Cảm ơn! Câu đầu tiên không xác định liệu là nội dung tệp hay tên tệp. Cập nhật.
Dru

Câu trả lời:


303

Sử dụng find:

find . -maxdepth 1 -name "*string*" -print

Nó sẽ tìm thấy tất cả các tệp trong thư mục hiện tại (xóa maxdepth 1nếu bạn muốn nó đệ quy) có chứa "chuỗi" và sẽ in nó trên màn hình.

Nếu bạn muốn tránh tệp chứa ':', bạn có thể nhập:

find . -maxdepth 1 -name "*string*" ! -name "*:*" -print

Nếu bạn muốn sử dụng grep(nhưng tôi nghĩ rằng không cần thiết cho đến khi bạn không muốn kiểm tra nội dung tệp), bạn có thể sử dụng:

ls | grep touch

Nhưng, tôi nhắc lại, findlà một giải pháp tốt hơn và sạch hơn cho nhiệm vụ của bạn.


Cảm ơn @Zagorax. Điều này làm nó chính xác. Ước gì lệnh không được lâu nhưng ayee :)
Dru

2
@Dru, Được sửa đổi để bao gồm các trường hợp nếu bạn muốn tránh dấu hai chấm. findlà một công cụ rất mạnh, nó phải bằng cách nào đó 'dài'. :)
Zagorax

Cảm ơn người đầu tiên đã làm nó hoàn hảo mà không trả lại bất kỳ nội dung.
Dru

3
@Dru, nếu bạn muốn nó 'ngắn hơn', bạn có thể tránh -printvì đây là hành vi mặc định và .vì đây là thư mục mặc định nơi nó kiểm tra.
Zagorax

1
find . -name "*string*"Hoạt động tuyệt vời quá. Loại bỏ .ném một lỗi vào cuối của tôi. Cảm ơn một lần nữa @Zagorax.
Dru

14

Sử dụng grep như sau:

grep -R "touch" .

-Rnghĩa là tái diễn. Nếu bạn không muốn đi vào thư mục con, hãy bỏ qua nó.

-icó nghĩa là "trường hợp bỏ qua". Bạn có thể thấy điều này đáng để thử là tốt.


Tuyệt quá. Tôi nhận thấy rằng một số nội dung tập tin theo a :. Có cách nào để giữ lại điều đó? Sử dụng một tùy chọn có lẽ?
Dru

1
Hãy thử:grep -R "touch" . | cut -d ":" -f 2
carlspring

Điều đó dường như chỉ sản xuất nội dung của các tập tin. Về cơ bản, bạn đã trả lời câu hỏi của tôi, tôi có thể cố gắng thực hiện một số hoạt động đào để giữ lại nội dung.
Dru

À ... bạn chỉ cần tên tập tin? Chạy: grep -R "touch" . | cut -d ":" -f 1 (xin lỗi phải đọc nhầm bạn).
carlspring

Cảm ơn @carlspring điều này thật thú vị. grephoặc trả về các tệp có nội dung và tên tệp chứa touchhoặc nội dung chứa touch, tôi không chắc đó là trường hợp nào. Trong danh sách các tệp được trả về, một nửa chứa touchtrong tiêu đề và nửa còn lại liên kết touchtrong cơ thể, không phải tiêu đề. Chỉ cần nhận ra điều này.
Dru

5

Các -maxdepthtùy chọn nên trước khi -namelựa chọn, như dưới đây.,

find . -maxdepth 1 -name "string" -print

1
Bạn phải đặt * trước và sau "chuỗi".
Aerin

3
find $HOME -name "hello.c" -print

Thao tác này sẽ tìm kiếm toàn bộ hệ thống $HOME(ví dụ /home/username/) cho bất kỳ tệp nào có tên là hello hello.c và hiển thị tên đường dẫn của chúng:

/Users/user/Downloads/hello.c
/Users/user/hello.c

Tuy nhiên, nó sẽ không phù hợp HELLO.Choặc HellO.C. Để phù hợp là trường hợp không nhạy cảm vượt qua -inametùy chọn như sau:

find $HOME -iname "hello.c" -print

Đầu ra mẫu:

/Users/user/Downloads/hello.c
/Users/user/Downloads/Y/Hello.C
/Users/user/Downloads/Z/HELLO.c
/Users/user/hello.c

Vượt qua -type ftùy chọn để chỉ tìm kiếm tệp:

find /dir/to/search -type f -iname "fooBar.conf.sample" -print
find $HOME -type f -iname "fooBar.conf.sample" -print

Các -inamehoạt động trên lệnh tìm phiên bản GNU hoặc BSD (bao gồm cả OS X). Nếu phiên bản lệnh find của bạn không hỗ trợ -iname, hãy thử cú pháp sau bằng cách sử dụng greplệnh:

find $HOME | grep -i "hello.c"
find $HOME -name "*" -print | grep -i "hello.c"

Hay là thử

find $HOME -name '[hH][eE][lL][lL][oO].[cC]' -print

Đầu ra mẫu:

/Users/user/Downloads/Z/HELLO.C
/Users/user/Downloads/Z/HEllO.c
/Users/user/Downloads/hello.c
/Users/user/hello.c

0

Nếu chuỗi ở đầu tên, bạn có thể làm điều này

$ compgen -f .bash
.bashrc
.bash_profile
.bash_prompt

3
compgenkhông phải là một cái búa thích hợp cho móng tay này. Công cụ ít sử dụng này được thiết kế để liệt kê các lệnh có sẵn và do đó, nó liệt kê các tệp trong thư mục hiện tại (có thể là tập lệnh) và nó không thể lặp lại cũng như nhìn qua phần đầu của tên tệp cũng như tìm kiếm nội dung tệp, làm cho nó Chủ yếu là vô dụng.
msanford

0

Một giải pháp thay thế cho nhiều giải pháp đã được cung cấp là sử dụng toàn cầu **. Khi bạn sử dụng bashvới tùy chọn globstar( shopt -s globstar) hoặc bạn sử dụng zsh, bạn chỉ có thể sử dụng toàn cầu **cho việc này.

**/bar

thực hiện tìm kiếm thư mục đệ quy cho các tệp có tên bar(có thể bao gồm tệp bartrong thư mục hiện tại). Lưu ý rằng điều này không thể được kết hợp với các hình thức toàn cầu khác trong cùng một đoạn đường dẫn; trong trường hợp đó, các *toán tử trở lại hiệu ứng thông thường của chúng.

Lưu ý rằng có một sự khác biệt tinh tế giữa zshbashở đây. Mặc dù bashsẽ đi qua các liên kết mềm đến các thư mục, nhưng zshsẽ không. Đối với điều này, bạn phải sử dụng toàn cầu ***/trong zsh.


0
find / -exec grep -lR "{test-string}" {} \;

1
Câu trả lời này được gắn cờ cho chất lượng thấp. Vui lòng giải thích những thay đổi được đề xuất của bạn làm.
Miroslav Glamuzina

-2
grep -R "somestring" | cut -d ":" -f 1

2
Đây dường như là một câu trả lời cho một câu hỏi khác - nhưng vì bạn không đưa ra lời giải thích nào, điều đó không rõ ràng đối với người hỏi hoặc với bất kỳ ai khác.
Toby Speight
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.