it-swarm-vi.com

lần cuối mở tập tin

Có thể lấy thời gian khi tệp được mở lần trước và sắp xếp tất cả các tệp trong một thư mục theo thời gian đó không?

101
student

Điều này phụ thuộc vào chính xác những gì bạn có nghĩa là "mở", nhưng nói chung, có. Có ba dấu thời gian thường được ghi lại:

  • mtime - được cập nhật khi nội dung tệp thay đổi. Đây là thời gian tập tin "mặc định" trong hầu hết các trường hợp.
  • ctime - được cập nhật khi tệp hoặc siêu dữ liệu (chủ sở hữu, quyền) của nó thay đổi
  • atime - được cập nhật khi tệp được đọc

Vì vậy, nói chung, những gì bạn muốn thấy là atime của một tệp. Bạn có thể nhận được điều đó với stat hoặc với ls. Bạn có thể dùng ls -lu để làm điều này, mặc dù tôi thích sử dụng ls -l --time=atime (cần được hỗ trợ trong hầu hết các bản phân phối Linux hiện đại) vì tôi không sử dụng nó thường xuyên và khi tôi có thể nhớ nó tốt hơn. Và đến sắp xếp theo thời gian, thêm -t cờ đến ls. Vì vậy, có bạn đi.

Có một cảnh báo lớn, mặc dù. Cập nhật atime mỗi khi đọc tệp gây ra rất nhiều IO thường không cần thiết, làm chậm mọi thứ. Vì vậy, hầu hết các bản phân phối Linux hiện mặc định là tùy chọn gắn kết hệ thống tập tin noatime, về cơ bản sẽ giết chết atimes hoặc cách khác relatime, chỉ cập nhật các thông báo một khi giới hạn đã vượt qua (thông thường một lần mỗi ngày) hoặc nếu các tập tin đã thực sự được sửa đổi kể từ lần đọc trước. Bạn có thể tìm thấy nếu các tùy chọn này được kích hoạt bằng cách chạy lệnh mount.

Ngoài ra, lưu ý rằng thời gian truy cập là bằng inode, không phải theo tên tệp, vì vậy nếu bạn có liên kết cứng, đọc từ một sẽ cập nhật tất cả các tên tham chiếu đến cùng một tệp.

Và, lưu ý rằng c không phải là "sáng tạo"; việc tạo không được theo dõi bởi các hệ thống tệp Unix/Linux, điều này có vẻ lạ nhưng thực sự có ý nghĩa bởi vì hệ thống tệp không có cách nào để biết liệu đó có phải là bản gốc hay không - có thể tệp đã được tạo bốn mươi năm trước và được sao chép ở đây. Và trên thực tế, nhiều trình soạn thảo tệp hoạt động bằng cách tạo các bản sao so với bản gốc. Nếu bạn cần thông tin đó, tốt nhất nên sử dụng hệ thống kiểm soát phiên bản như git.

182
mattdm

ls -ltu liệt kê tất cả các tệp, hiển thị và sắp xếp theo thời gian truy cập.

Từ man ls:

-u     with -lt: sort by, and show, access time with -l: show access
       time and sort by name otherwise: sort by access time
21
Shawn J. Goff

Lệnh find là tốt nhất cho việc này. Xem -ctime, -mtime-atime tùy chọn

4
GBH

Nếu danh sách của bạn dành cho tiêu dùng của con người, hãy sử dụng ls với một trong các cờ sắp xếp ngày (-tu Để truy cập (đọc), chỉ -t Để sửa đổi thời gian (ghi) -tc Cho thời gian thay đổi inode). Xem câu trả lời của mattdm để biết thêm thông tin (cụ thể là cảnh báo về -a Và định nghĩa của -c).

Nếu đây là để tiêu thụ chương trình, phân tích đầu ra của ls là có vấn đề . Nếu Shell của bạn là zsh, bạn không cần ls anyway: zsh có vòng loại toàn cầu để sắp xếp các trận đấu bằng cách tăng quyền truy cập (*(Oa)), thay đổi inode (*(Oc)) hoặc sửa đổi (*(Om)) thời gian. Một chữ thường o sắp xếp theo độ tuổi tăng dần.

act_on_files_by_date *(Om)

Mặt khác, nếu bạn biết rằng tên tệp không chứa bất kỳ ký tự dòng mới hoặc không in được (trong ngôn ngữ hiện tại), thì bạn có thể làm một cái gì đó như

ls -t | while read -r name; do act_on_one_file "$name"; done
ls -t | xargs -I {} act_on_one_file {}

Nếu bạn muốn gọi một lệnh trên nhiều tệp cùng một lúc, bạn cần thiết lập nhiều hơn. Lưu ý rằng act_on_files_by_date $(ls -t) không hoạt động như thế này, vì tên tệp chứa ký tự đại diện hoặc khoảng trắng sẽ được mở rộng trong kết quả của việc thay thế lệnh. Đoạn mã sau hoạt động miễn là không có tên tệp nào chứa dòng mới hoặc ký tự không in được:

IFS='
'
set -f
act_on_files_by_date $(ls -t)
set +f
unset IFS

Nếu bạn muốn đối phó với các tên tệp tùy ý, bạn sẽ có một khoảng thời gian rất khó khăn mà không cần dùng đến các công cụ mạnh hơn so với Shell tiêu chuẩn: zsh, Perl, python