Làm phẳng đầu ra của một danh sách thư mục đệ quy


7

Có cách nào để liệt kê tất cả các tệp trong cây thư mục trong một danh sách, được sắp xếp theo thời gian sửa đổi trên Linux không?

ls -Rlt 

liệt kê các tệp đệ quy, nhưng chúng được nhóm theo các thư mục khác nhau trong đầu ra và kết quả là đầu ra không được sắp xếp một cách tổng thể. Chỉ có nội dung của mỗi thư mục được sắp xếp theo thời gian.


Bạn cũng muốn liệt kê các thư mục hoặc chỉ các tập tin?
terdon

Câu trả lời:


11

Có, bạn có thể làm điều này với GNU find. Nếu tên tệp của bạn không chứa dòng mới, bạn có thể làm:

find -printf '%T@ %p\n' | sort -gk1,1

Giải trình

  • Các -printftùy chọn findcó thể in tất cả các loại thông tin. Trong trường hợp này, chúng tôi đang sử dụng:

    %Tk    File's last modification time in the format specified  by
           k, which is the same as for %A.
    @      seconds  since Jan. 1, 1970, 00:00 GMT, with fractional part.
    %p     File's name.
    

    Vì vậy, %T@ %p\nsẽ in thời gian sửa đổi của tệp tính bằng giây kể từ epoch ( %T@), khoảng trắng và sau đó là tên tệp ( %p).

  • Chúng sau đó được chuyển đến sortđược yêu cầu sắp xếp số ( -n) trên trường đầu tiên ( -k1,1).

Lưu ý rằng điều này sẽ trả về tất cả các tập tin và thư mục. Để giới hạn nó chỉ với các tệp thông thường (không có thư mục, tệp thiết bị, liên kết, v.v.) thêm -type fvào findlệnh của bạn .

Để có được ngày con người có thể đọc được, bạn có thể xử lý đầu ra bằng GNU date:

find -printf '%T@ %p\t\n' | sort -gk1,1 | 
    perl -lne 's/([^ ]*)//;chomp($i=`date -d \@$1`); print "$i $_"'

Ở đây, perllệnh thay thế chuỗi ký tự không phải không gian đầu tiên (ngày) bằng chính nó được xử lý bởi GNU date.


Ở trên sẽ thất bại cho tên tập tin có chứa dòng mới. Để đối phó với các dòng mới, sử dụng:

find -printf '%p\t%T@\0' | sort -zt$'\t' -nk2 | tr '\0' '\n'

Đó là điều tương tự ngoại trừ việc findsẽ xuất ra \0thay vì \nở cuối mỗi tên tệp. GNU sortcó thể xử lý đầu ra được phân tách bằng null để nó vẫn có thể sắp xếp chính xác. Lệnh cuối cùng trdịch \0ngược lại \n.


Đó là những gì tôi đang làm tốt (với thời gian đầu tiên). Nó cũng cần findutils GNU.
chexum

@chexum ah vâng, cảm ơn. Tôi tiếp tục quên rằng đó -printfkhông phải là POSIX.
terdon

cảm ơn đã giải thích Tôi có thể sửa đổi lệnh này để in thời gian sửa đổi ở định dạng có thể đọc được không?
mahela007

@ mahela007 có. Bạn cần sử dụng dateđể định dạng lại nó : find -printf '%T@ %p\t\n' | sort -gk1,1 | sed -E "s/([^ ]*)/$(date -d \1)/". Xem câu trả lời cập nhật. Tôi cũng đã sửa lỗi sử dụng (hoàn toàn không cần thiết) của các tab.
terdon

@mikeerv thực sự tôi đã không, cảm ơn. Nó nên hoạt động ngay bây giờ.
terdon

5

Với zsh:

print -rl -- **/*(D.om)

** / * phù hợp với bất kỳ cấp thư mục con nào (và không tuân theo liên kết tượng trưng). D.vòng loại liệt kê các tập tin thường xuyên, omsắp xếp chúng theo thời gian sửa đổi, mới nhất trước tiên.

Nếu bạn muốn tên tệp được liệt kê mà không có phần thư mục, hãy thêm công cụ tsửa đổi lịch sử:

print -rl -- **/*(D.om:t)

zsh là gì ()
mahela007

@ mahela007: Đây là một vỏ unix khác, với nhiều tính năng nâng cao được thêm vào zsh.org
cuonglm

0

tốt, nếu bạn đang nói về nhiều ngàn tệp - và vượt quá ARG_MAXgiới hạn của bạn - thì nó sẽ không được phát hành tốt, nhưng giải pháp đơn giản nhất là:

find . ! -type d -exec ls -t {} +

... Nó sẽ gọi lscho mỗi lô <=ARG_MAXtệp mà nó có thể tìm thấy. Không có hạn chế tùy ý đối với các ký tự trong tên đường dẫn, chỉ trên số lượng đối số tối đa có thể được xử lý cùng nhau.

Nó sẽ ghi đầu ra giống hệt với findđầu ra của. Tất nhiên, bạn có thể sử dụng bất kỳ tùy chọn nào khác, chẳng hạn như -lhoặc GNU -h. Dưới đây là một vài thứ được liệt kê từ một cây nhỏ mà tôi đã tạo ra một tuần trước:

find . ! -type d -exec ls -lht {} +

-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir/dir1/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir/dir2/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir/dir3/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir2/dir1/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir2/dir2/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir2/dir3/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir/file1
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir/file2
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir/file3
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir2/file1
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir2/file2
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir2/file3

... mà rõ ràng là không được nhóm theo thư mục.

Trên máy của tôi ...

getconf ARG_MAX

2091752

... nhưng tôi không nghĩ đó là thực tế. Tôi nghĩ rằng trung bình khoảng 65 nghìn hoặc hơn.

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.