Sắp xếp đầu ra của find -exec ls


14

Có thể cho đầu ra của find … -exec ls -ls ;sắp xếp theo thứ tự, theo tên tệp?

Đây là lệnh cron của tôi:

find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;

Lệnh này hoạt động tốt, đối với hầu hết các phần. Nhưng kết quả không được sắp xếp theo bất kỳ chuỗi có ý nghĩa. Sẽ rất hữu ích nếu chúng được sắp xếp theo trường tên tệp.


1
Sử dụng zsh? ls -ls **/*(.)
Kevin

@Kevin Không hoàn toàn - lssẽ sắp xếp.
Gilles 'SO- đừng trở nên xấu xa'

Câu trả lời:


14

Tôi giả sử rằng tên tệp của bạn không chứa dòng mới.

find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10

Sử dụng +thay vì ;chấm dứt -exechành động làm cho nó nhanh hơn bằng cách gộp các lệnh ls. Bạn có thể sắp xếp bằng đường ống thông qua sortlệnh; bảo nó bắt đầu sắp xếp ở trường thứ 10 (9 đầu tiên là siêu dữ liệu: khối, quyền, số liên kết, người dùng, nhóm, kích thước và 3 trường ngày / giờ). Tùy chọn -ncho biết lssử dụng các giá trị số cho người dùng và nhóm, điều này tránh nguy cơ tên người dùng hoặc nhóm có chứa khoảng trắng.

Ngoài ra, với zsh, bạn có thể thoát khỏi bất kỳ giả định nào về bất kỳ tên nào bằng cách sử dụng vòng loại toàn cầu để thu thập và sắp xếp các tệp và zargschạy lsnhiều lần nếu dòng lệnh quá dài. Bạn cần GNU ls(cụ thể là -ftùy chọn của nó ) để tránh sắp xếp lại theo ls(cách tiếp cận khác sẽ là mô phỏng lsvới zsh's zstat).

autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf

Cảm ơn bạn rất nhiều! Sử dụng lệnh đầu tiên bạn đã gửi sẽ sắp xếp. Con số vẫn là 10 nếu tôi sử dụng đường dẫn ngắn hơn? Ví dụ: nếu tôi chạy cùng một lệnh từ / home / setefgge thay vì từ public_html?
MaJ

@MaJ 10 là số trường bị bỏ qua, nó không liên quan gì đến kích thước của tên tệp.
Gilles 'SO- ngừng trở nên xấu xa'

Cảm ơn bạn. Tôi đánh giá cao sự giúp đỡ của bạn, và cũng là sự giúp đỡ của mọi người khác. Tôi xem xét vấn đề này được giải quyết. Lệnh cron của tôi hiện đang sắp xếp các tập tin. Đây là lần đầu tiên tôi gửi câu hỏi đến Stackexchange. Tôi không thấy tùy chọn "Đã giải quyết". Nếu bất kỳ ai trong số các bạn biết làm thế nào để đăng bài này như đã giải quyết, xin vui lòng tiếp tục và làm như vậy. Cảm ơn!
MaJ

@MaJ Điều gần nhất chúng ta phải đánh dấu một câu hỏi đã được giải quyết là đánh dấu một trong những câu trả lời là được chấp nhận. Chỉ có bạn, người hỏi, có thể làm như vậy. Để làm điều này, nhấp vào dấu kiểm bên cạnh câu trả lời giúp bạn nhiều nhất. Nếu bạn chấp nhận câu trả lời, bạn sẽ nhận được thêm 2 điểm danh tiếng và sau đó bạn sẽ có thể nâng cấp bài đăng; bạn có thể upvote tất cả các bài viết mà bạn thấy hữu ích. Để biết thêm thông tin, hãy xem trang tham quantrang trợ giúp về những gì khi ai đó trả lời câu hỏi của bạn .
Gilles 'SO- ngừng trở nên xấu xa'

1

Tại sao không dẫn đến kết quả tìm kiếm thông qua sắp xếp và sau đó thực hiện ls cho mỗi dòng?

find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done

1

POSIX có điều này để nói về ngày trong ls -ldanh sách ong:

Các <date and time>lĩnh vực phải có các ngày thích hợp và dấu thời gian khi các tập tin được sửa đổi lần cuối. Trong miền địa phương POSIX, trường sẽ tương đương với đầu ra của lệnh ngày sau:

date "+%b %e %H:%M"

... nếu tệp đã được sửa đổi trong sáu tháng qua, hoặc:

date "+%b %e %Y"

Cân nhắc điều này và đảm bảo rằng nếu có bất kỳ dòng mới nào trong tên tệp thì chúng được đặt đúng vị trí với ls -qtùy chọn được chỉ định POSIX , việc chuẩn bị một biểu thức chính xác cho lskết quả mà không cần find:

d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"

###OUTPUT###
Jul  5 Jul  4

grepcho điều đó và bạn sẽ chỉ trả lại các dòng có chứa các chuỗi đại diện cho ngày hôm nay hoặc ngày hôm qua. Lệnh sau thêm vào đó một chút:

ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

ls các tùy chọn bao gồm:

  1. -a trả về tất cả các tệp trong một thư mục - bao gồm cả những tệp bắt đầu bằng một .dot
  2. -l danh sách dài
  3. -R liệt kê đệ quy tất cả các thư mục con
  4. -c hiển thị thời gian sửa đổi thay vì thời gian truy cập
  5. -qtrả về shell toàn cầu ?thay vì các \tký tự ab không thể in hoặc ab trong tên tệp

Những kết quả đó được chuyển qua |pipetệp sedchỉ khớp với:

  1. Dòng trống trước tên đường dẫn và dòng sau
  2. Các dòng bắt đầu bằng - (nói cách khác - không ddành cho thư mục) cũng chứa của bạn date.
  3. Nó không in các dòng tên đường dẫn trừ khi thư mục họ đặt tên thực sự chứa các tệp bạn đã lọc.

Đầu ra trông như thế này:

ls -alRcq --color=always | 
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv   2086 Jul  4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv   2657 Jul  4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv    681 Jul  5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul  5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul  4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul  4 13:34 shot-2014-06-22_17-11-06.jpg

./.cache/efreet:
-rw------- 1 mikeserv mikeserv  37325 Jul  4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv  37325 Jul  4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  16037 Jul  4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv   3117 Jul  4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul  4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv  18589 Jul  4 23:30 icons_hicolor_localhost.eet

./.config:
-rw-r--r-- 1 mikeserv mikeserv   30 Jul  4 19:10 pavucontrol.ini

./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul  4 13:36 conf.tar.lz4.bak

Vâng, nó thậm chí hoạt động với LS_COLORS- có lẽ là ưu tiên thấp cho cronkhóa học của bạn , nhưng, hey các tùy chọn của bạn đang mở.

Trong mọi trường hợp, điều này cung cấp một số lợi thế đáng kể so với một số giải pháp có thể khác.

  1. Ở vị trí đầu tiên find+ lsliên quan đến nhiều yêu cầu - điều này chỉ liên quan đến một lsquy trình duy nhất và đây là lý do tại sao nó có thể sắp xếp một cách đáng tin cậy mọi thứ - theo mặc định - và do đó sortcũng được thực hiện phụ trợ.

  2. Bất kỳ giải pháp liên quan findsortlslà khá nhiều làm tất cả các công việc hai lần. lsfindcả hai sẽ giải quyết mọi tên đường dẫn và statmọi tệp. lssortcả hai sẽ sắp xếp tất cả các kết quả. Nó có lẽ là tốt nhất thay vì chỉ sử dụng duy nhất ls.

  3. Sau đó, tất nhiên có datesedmột phần của câu trả lời này. Điều quan trọng cần lưu ý là bạn làm phần khó và lấy regex trước - và chỉ một lần - và sau đó bạn chỉ cắt một danh sách kết quả duy nhất thay vì nói, nhận kết quả, nhận kết quả, sắp xếp kết quả và sắp xếp kết quả.

  4. Điều này không phá vỡ tên tập tin có chứa dòng mới, như các giải pháp khác có thể sẽ. Giải pháp này có những cảnh báo riêng - mà tôi sẽ giải thích tiếp theo - nhưng chúng chỉ trong vài phút và dễ dàng xử lý. Theo tôi, đây là giải pháp mạnh mẽ nhất ở đây.

Có hai trường hợp lệnh trên có thể gây ra sự cố cho bạn. Đầu tiên liên quan đến các khối ?trong tên tập tin - trong khi đó nó đã là một giải pháp mạnh mẽ hơn bất kỳ giải pháp nào khác được cung cấp ở đây, và khả năng bạn sẽ gặp phải ?tất cả là đủ nhỏ, có khả năng giải quyết các khối đó có thể khớp nhiều hơn một tên tệp. Xin vui lòng xem điều này để biết thêm thông tin về chủ đề này.

Khả năng khác liên quan đến dương tính giả - ví dụ nếu bạn có tên tệp thực sự khớp với datechuỗi mà chúng tôi đang tìm kiếm grepnhưng điều đó không thực sự được sửa đổi vào một trong những ngày đó. Tôi không tính đó là một vấn đề, nhưng, nếu có, hãy hỏi về nó và tôi có thể giúp bạn làm cho regex cụ thể hơn để xử lý việc này.


0

Bạn thực sự có thể sử dụng kết hợp find, xargs và ls.

Đây là một lệnh mẫu: find . -type f -print0 | xargs -0 ls -lt

  • find sẽ đệ quy tìm kiếm tất cả các tệp trong thư mục hiện tại.
  • xargs sẽ chuyển danh sách các tệp này cho lslệnh trong một cuộc gọi duy nhất (được cung cấp findtrả về ít hơn ARG_MAXcác tệp).
  • ls -lt sẽ sắp xếp các tệp này theo thời gian và định dạng đầu ra

Để truy xuất hệ thống của ARG_MAXbạn, bạn có thể gõ:

$ getconf ARG_MAX
> 2621440

-1
ls -l $(find /home/setefgge/public_html -type f -ctime -1 | sort)

1
lskhông tự sắp xếp, do đó, đường ống đầu ra findthông qua sortlà vô ích. Hơn nữa, lệnh của bạn mang tên tệp chứa khoảng trắng (trong số những người khác) và sẽ thất bại nếu có quá nhiều tên tệp.
Gilles 'SO- ngừng trở nên xấu xa'
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.