Tìm tập tin trong nhiều tên thư mục


44

Tôi cố gắng để danh sách tất cả các file từ dir1, dir2, dir3dir4đó có thể là bất cứ nơi nào trong như một thư mục con của tôi cwdbằng cách sử dụng findlệnh. Tôi đã thử những điều sau đây nhưng không thành công:

find . -type f -regextype posix-egrep -regex 'dir1/.+|dir2/.+|dir3/.+|dir4/.+'

Tôi cũng đã cố gắng posix-extended. Làm thế nào tôi có thể liệt kê các tập tin này?


tìm thấy . -type f -regextype sed -regex ". * / dir [1-4] / [a-z0-9] *" .. câu trả lời ngắn nhất cho đến nay :) xem câu trả lời bên dưới .. unix.stackexchange.com/a/390333 / 242983
alpha_989

Câu trả lời:


59

Và nếu bạn muốn tìm kiếm ba thư mục có tên foo, barbazcho tất cả *.pycác file, sử dụng lệnh này:

find foo bar baz -name "*.py"

Vì vậy, nếu bạn muốn hiển thị các tập tin dir1 dir2 dir3sử dụngfind dir1 dir2 dir3 -type f

thử đi find . \( -name "dir1" -o -name "dir2" \) -exec ls '{}' \;


Tôi nên đã làm rõ. Tôi có thể không có đường dẫn đến các tập tin tôi muốn tìm kiếm. Tôi chỉ biết họ là thư mục con của thư mục hiện tại.
Aaron

sử dụng ./dirthay vìdir
harish.venkat

Các dir vẫn cần phải ở trong cwd, nó có thể thấp hơn hai cấp (ví dụ ./path/to/dir1), trong trường hợp đó ./dir1sẽ không tồn tại.
Aaron

chỉnh sửa câu trả lời.
harish.venkat

8

Tốt nhất là sử dụng chỉ thị -path:

find .  \( -type f -and -path '*/dir1/*' -or -path '*/dir2/*' -or -path '*/dir3/*' -or -path '*/dir4/*' \)

Có nghĩa là: tìm tất cả các tệp trong thư mục hiện tại nơi có 'dir1' hoặc 'dir2' hoặc 'dir3' hoặc 'dir4' trong đường dẫn.


Bạn đã có dấu ngoặc đơn ở sai vị trí. Xem thêm -a-ođể biết tương đương tiêu chuẩn của GNU -and/ -or.
Stéphane Chazelas

4

Chỉ cần để cho mọi người biết. Thêm .*/trước khi dirgiải quyết vấn đề vì regexnó phù hợp với đường dẫn đầy đủ.


3

Đây là ý tưởng đầu tiên của tôi sau khi đọc các câu trả lời trước:

find . -type f -regextype posix-egrep -regex ".*/(dir1|dir2|dir3|dir4)/.+"

Điều này có tính đến, rằng regex phải khớp với toàn bộ tên tệp và dễ hiểu hơn.


2

Mẫu nhanh (!) Tìm các tệp cụ thể (access_log) ở nhiều vị trí được xác định bởi ký tự đại diện (thư mục chính) và thư mục nhật ký apache2 chung áp dụng lọc tên để loại trừ nhật ký ssl và ghi nhật ký cũ. Không trả lời trực tiếp câu hỏi ở đây nhưng có thể hữu ích cho người tìm thấy các hướng dẫn này (như tôi).

find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*"

Hãy cẩn thận với không gian, đặc biệt gần \(\).

Nhân tiện, tôi đã sử dụng nó cho apachetop, để tìm hầu hết các trang web hoạt động trong máy chủ của tôi.

apachetop -d1 -s9 -p $(find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*" -print | sed 's/^/-f '/)

2

bạn không cần chỉ định dir1 thành dir4 theo tên nếu bạn đang sử dụng regextype

find . -type f -regextype sed -regex ".*/dir[1-4]/[^/]*"
  • type f: tìm tập tin không phải thư mục
  • regextype sed: sử dụng sed regextype
  • regex: tìm kiếm bằng regex trong toàn bộ đường dẫn
  • ".*/dir[1-4]/[a-z0-9]*":. * ở đầu có nghĩa là bất kỳ số lượng ký tự nào có thể thuộc loại (char / number / backslash (/), v.v.); dir [1-4] có nghĩa là tìm "dir" theo sau là một số từ 1 đến 4; / [^ /] * nói rằng sau dir1-4 bỏ qua bất kỳ tên đường dẫn nào có / trong đó, vì vậy nó chỉ trả về các tệp trong thư mục dir1-dir4 và bỏ qua mọi thư mục con có thể nằm trong dir1-dir4.

đã tạo một thư mục để bạn kiểm tra nó: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution04092017


(1) Chúng tôi có thể không bao giờ biết tình huống hoặc yêu cầu chính xác của Aaron, nhưng các câu trả lời khác đã đưa ra quyết định thận trọng rằng anh ta có bốn thư mục, tên của họ không được chỉ định. (Họ có thể là red, green, blueyellow, hoặc họ có thể được John, Paul, GeorgeRingo.) Câu trả lời của bạn giả định rằng họ là nghĩa đen dir1 , dir2, dir3dir4. Tiết (Cont'd)
Scott

(Tiếp theo) Nhiều (2) Tại sao bạn cho rằng Aaron không muốn tìm kiếm các thư mục con? Anh ta dường như đang nói rằng anh ta làm. (3) Tại sao bạn giới hạn tìm kiếm đối với các tệp có tên chỉ chứa chữ cái và chữ số viết thường (không bao gồm những thứ như foo_bar, foo.txtFOO)? (4) Tại sao văn bản của bạn giải thích /[^/]*khi câu trả lời của bạn không sử dụng nó?
Scott

Xin chào Scott, đó là nhận xét của bạn.
alpha_989

(1-3). anh ta đề cập "Tôi đang cố gắng liệt kê tất cả các tệp từ dir1, dir2, dir3 và dir4 " có thể ở bất kỳ đâu trong thư mục con của cwd của tôi , điều đó có nghĩa là dir1-dir4 có thể ở bất cứ đâu, nhưng anh ta muốn tìm đúng tệp trong dir1-dir4. Tất nhiên, nếu không phải là dir1-dir4, bạn phải đổi nó thành tên cụ thể bằng cách sử dụng màu đỏ \ | blue \ | green \ | vv ..
alpha_989

4. lỗi đánh máy ở đó .. Tôi đã sử dụng [a-z0-9] * trước đó..thì nhận ra [^ /] * ngắn hơn và bao quát hơn..forgot để thay đổi nó khi tôi đăng bài này. Cảm ơn ý kiến ​​cẩn thận của bạn.
alpha_989

0

Tôi biết bạn đã chỉ định rằng sử dụng find, nhưng chỉ để hiển thị các tùy chọn khác có thể được sử dụng, bạn có thể sử dụng xargs:

find . -type d | grep -E "dir1$|dir2$" | xargs ls  

find . -name "dir1" -or -name "dir2" | xargs ls

Bạn có thể có một tệp có tên "thư mục" có chứa một cái gì đó như:

$ cat folders
dir1
dir2
dir3
dir4

Sau đó, bạn có thể làm một cái gì đó như thế này:

$ cat folders | xargs -I % find . -type d -name % | xargs ls
./Documents/dir1:
file1  file2  file3  file4

./Documents/dir2:
file1  file2  file3  file4

./Documents/dir3:
file1  file2  file3  file4

./Documents/dir4:
file1  file2  file3  file4

Theo ý kiến ​​của tôi, tôi cảm thấy linh hoạt hơn tìm kiếm -exec. Ngoài ra, bạn có thể làm một số thứ điên rồ như

$ cat << EOF | xargs -I {} find ~ -name "{}" | xargs ls
> dir1
> dir2
> dir3
> EOF
/home/user/Documents/dir1:
file1  file2  file3  file4

/home/user/Documents/dir2:
file1  file2  file3  file4

/home/user/Documents/dir3:
file1  file2  file3  file4
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.