Tìm tập tin mới nhất theo ngày sửa đổi


38

Nếu tôi muốn tìm tệp mới nhất (mtime) trong thư mục (lớn) chứa thư mục con, tôi sẽ làm thế nào?

Rất nhiều bài đăng tôi đã tìm thấy đề xuất một số biến thể của ls -lt | head(thật thú vị, nhiều đề xuất ls -ltr | taillà giống nhau nhưng kém hiệu quả hơn), điều đó tốt, trừ khi bạn có thư mục con (tôi làm).

Sau đó, một lần nữa, bạn có thể

find . -type f -exec ls -lt \{\} \+ | head

mà chắc chắn sẽ thực hiện thủ thuật cho càng nhiều tệp có thể được chỉ định bởi một lệnh, tức là nếu bạn có một thư mục lớn , -exec...\+sẽ đưa ra các lệnh riêng biệt; do đó, mỗi nhóm sẽ được sắp xếp theo lsbên trong nhưng không vượt quá tổng số; do đó, người đứng đầu sẽ chọn mục cuối cùng của đợt đầu tiên.

Có câu trả lời nào không?


btw, bạn không cần bất kỳ dấu gạch chéo ngược nào.
enzotib

@enzotib: bạn làm ( \ + ), nếu không bạn sẽ nhận đượcfind: missing argument to '-exec'
sắp xếp

@arrange: Tôi không có lỗi này, vì +không có ý nghĩa gì bash, vì vậy không cần phải thoát nó.
enzotib

@enzotib: bạn nói đúng, lỗi của tôi, xin lỗi
sắp xếp

Câu trả lời:


46

Bạn không cần phải lặp lại các lệnh bên ngoài (vì ls) vì findcó thể làm tất cả những gì bạn cần thông qua -printfhành động:

find /path -printf '%T+ %p\n' | sort -r | head

1
Vâng, tôi đã đưa ra find . -type f -exec stat --format=%y \{\} \+ | sort -r | head -n1nhưng giải pháp của bạn là sạch hơn nhiều!
Giàu

3
Chỉ | cut -d ' ' -f2nhận được tên tệp
qwr

Bạn cũng có thể loại bỏ đầu ra headđể bao gồm một số dòng nhất định. Tôi chỉ cần dòng đầu tiên, vì vậy tôi đã sử dụnghead -n 1
Timmah

8

Tôi đã có một vấn đề tương tự ngày hôm nay, nhưng tôi đã tấn công nó mà không có find. Tôi cần một cái gì đó ngắn để tôi có thể chạy qua sshđể trả lại tập tin được chỉnh sửa gần đây nhất trong thư mục nhà của tôi. Đây là những gì tôi nghĩ ra:

ls -tp | grep -v /$ | head -1

Các -ptùy chọn để lsthêm một gạch chéo để thư mục, grep -vđể loại bỏ việc dòng kết thúc bằng một dấu gạch chéo (aka, tất cả các thư mục), và các head -1giới hạn đầu ra vào một tập tin duy nhất.

Điều này ít dài dòng hơn nhiều so với việc sử dụng findnếu tất cả những gì bạn muốn trả về là tên tệp.


Điều này không xử lý các thư mục con.
Clément

4

Đây là trên hệ thống của tôi nhanh hơn printf, mặc dù tôi không hiểu tại sao

find /path -type f -exec stat -c "%y %n" {} + | sort -r | head

Tôi xác nhận, là nhanh hơn.
enzotib

Một điểm nữa, ... | sort -r | head -n1 | cut -d " " -f 4-nếu bạn chỉ muốn lấy tên tệp.
林果

Tôi chỉ tìm thấy sort -rsẽ sai nếu tên tệp trên nhiều dòng tồn tại.
林果

2

EDIT: Tôi đoán bài đăng này không "không đặc biệt hữu ích" như tôi nghĩ. Đây là một giải pháp thực sự nhanh chóng, chỉ theo dõi tệp được sửa đổi gần đây nhất (thay vì sắp xếp toàn bộ danh sách các tệp):

find . -type f -printf '%T@ %p\n' | awk 'BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' '

Trải rộng trên nhiều dòng cho rõ ràng như sau:

find . -type f -printf '%T@ %p\n' | awk '
    BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; }
    {
        if ($1 > mostrecenttime)
            { mostrecenttime = $1; mostrecentline = $0; }
    }
    END { print mostrecentline; }' | cut -f2- -d ' '

Kết thúc EDIT


Không phải là một bài viết đặc biệt hữu ích nhưng vì 'sắp xếp' đang thảo luận về tốc độ, tôi nghĩ tôi muốn chia sẻ điều này.

sắp xếp các giải pháp và enzotib liên quan đến việc liệt kê tất cả các tệp trong thư mục với mtimes của họ và sau đó sắp xếp. Như bạn biết sắp xếp là không cần thiết để tìm tối đa. Việc tìm kiếm tối đa có thể được thực hiện trong thời gian tuyến tính nhưng việc sắp xếp mất n log (n) thời gian [Tôi biết sự khác biệt không nhiều, nhưng vẫn;)]. Tôi không thể nghĩ ra một cách gọn gàng để thực hiện điều này. [EDIT: Một cách gọn gàng (mặc dù trông bẩn) và triển khai nhanh được cung cấp ở trên.]

Điều tốt nhất tiếp theo - Để tìm tệp được chỉnh sửa gần đây nhất trong một thư mục, hãy tìm đệ quy tệp được chỉnh sửa gần đây nhất trong mỗi thư mục con cấp 1. Hãy để tập tin này đại diện cho thư mục con. Bây giờ sắp xếp các tệp cấp 1 cùng với các đại diện của thư mục con cấp 1. Nếu số lượng tệp cấp 1 và thư mục con của mỗi thư mục gần như là một hằng số, thì quá trình này sẽ mở rộng tuyến tính với tổng số tệp.

Đây là những gì tôi đã đưa ra để thực hiện điều này:

findrecent() { { find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1; }
findrecent .

Tôi chạy cái này và gặp một loạt find: findrecent: No such file or directorylỗi. Lý do: -exec của find chạy trong một shell khác. Tôi đã thử xác định công cụ tìm kiếm trong .bashrc, .xsessionrc nhưng chúng không giúp được gì [Tôi đánh giá cao sự giúp đỡ ở đây]. Cuối cùng, tôi đã dùng đến việc đặt

#!/bin/bash
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

trong một kịch bản được gọi findrecenttrong PATH của tôi và sau đó chạy nó.

Tôi chạy này, tiếp tục chờ đợi và không có đầu ra. Để chắc chắn rằng tôi đã không xử lý bất kỳ vòng lặp vô hạn nào, tôi đã sửa đổi tệp thành

#!/bin/bash
echo "$1" >&2
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

và thử lại. Nó đã hoạt động - nhưng mất 1 phút 35 giây trên máy chủ của tôi - các giải pháp của sắp xếp và enzotib lần lượt mất 1,69, 1,95 giây!

Quá nhiều cho sự vượt trội của O (n) so với O (n log (n))! Chết tiệt bạn gọi chức năng trên cao! [Hay nói đúng hơn là tập lệnh gọi]

Nhưng tập lệnh này có quy mô tốt hơn các giải pháp trước đó và tôi cá rằng nó sẽ chạy nhanh hơn chúng trên ngân hàng bộ nhớ của google; D


2

Sử dụng perltrong liên hợp với find:

 find my_directory -type f -printf '%T@\t%p\n' | perl -ane '@m=@F if ($F[0]>$m[0]); END{print $m[1];}'

Bạn nhận được tên của tệp có epoch lớn nhất == tệp cuối cùng được sửa đổi.


1

Nó gần như không hợp thời trang, nhưng cũng có thể đạt được điều này với Midnight Commander : tìm kiếm *, điều chỉnh kết quả, sắp xếp theo thời gian sửa đổi theo thứ tự ngược lại.

Rõ ràng, nó chậm hơn một chút so với find- thư mục nhà của tôi, chứa 922000 tệp, được sắp xếp mctrong gần 14 phút trong khi findchi tiêu ít hơn 5 - nhưng có một số lợi ích:

  • Có lẽ tôi sẽ mất nhiều thời gian hơn sau đó chênh lệch 9 phút để phát minh ra một lời mời tìm kiếm thích hợp :)

  • ít có khả năng xảy ra lỗi (quên chỉ định -r để sắp xếp, v.v. - bắt đầu lại)

  • có thể chơi với tập kết quả bằng cách thay đổi thứ tự sắp xếp, v.v. - mà không cần truy vấn lại các tệp.

  • chỉ có thể thực hiện các thao tác tệp trên một số tệp từ tập kết quả - tức là sắp xếp theo kích thước, xóa một vài tệp lớn không cần thiết

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.