it-mot-dan-vi.com

Làm thế nào để tôi làm một ls và sau đó sắp xếp kết quả theo ngày được tạo?

Theo thứ tự ngày được đặt hàng bởi? Chắc chắn không phải là thứ tự chữ và số.

ls -lt sắp xếp theo thời gian sửa đổi. Nhưng tôi cần thời gian sáng tạo.

124
InquilineKea

Hầu hết các thông báo không có khái niệm về thời gian tạo tập tin. Bạn không thể thực hiện ls in vì thông tin không được ghi lại. Nếu bạn cần thời gian tạo, hãy sử dụng hệ thống kiểm soát phiên bản : xác định thời gian tạo là thời gian đăng ký.

Nếu biến thể unix của bạn có thời gian tạo, hãy xem tài liệu của nó. Ví dụ: trên Mac OS X (ví dụ duy nhất tôi biết về¹), sử dụng ls -tU. Windows cũng lưu trữ thời gian tạo, nhưng không phải lúc nào nó cũng tiếp xúc với các cổng của tiện ích unix, ví dụ Cygwin ls không có tùy chọn để hiển thị. Tiện ích stat có thể hiển thị thời gian tạo, được gọi là thời gian sinh Sinh trực tiếp trong các ứng dụng GNU, vì vậy, theo Cygwin, bạn có thể hiển thị các tệp được sắp xếp theo thời gian sinh với stat -c '%W %n' * | sort -k1n.

Lưu ý rằng ctime (ls -lc) không phải là thời gian tạo tệp , đó là inode thay đổi thời gian. Thời gian thay đổi inode được cập nhật bất cứ khi nào bất cứ điều gì về tệp thay đổi (nội dung hoặc siêu dữ liệu) ngoại trừ thời gian không được cập nhật khi tệp chỉ được đọc (ngay cả khi thời gian được cập nhật). Cụ thể, ctime luôn luôn gần đây hơn mtime (thời gian sửa đổi nội dung tệp) trừ khi mtime được đặt rõ ràng thành một ngày trong tương lai.

100

Thật không may, API stat(2) không cung cấp cách lấy thời gian tạo tệp, vì nó là không bắt buộc theo tiêu chuẩn Unix.

Tuy nhiên, một số hệ thống tập tin, như ext4, hãy lưu thông tin này trong tập tin metadatas. Không có cách tiêu chuẩn nào để có được nó, nhưng có một cách (ext chỉ hệ thống tập tin):

debugfs -R 'stat partition/relative/path/to/file' /dev/sda1

Bạn sẽ nhận được một cái gì đó giống như đề cập đến crtime ( khôngctime!) Nếu bạn sử dụng ext4.

 ctime: 0x513a50e5:d4e448f0 -- Fri Mar  8 21:58:13 2013
 atime: 0x513dd8f1:04df0b20 -- Mon Mar 11 14:15:29 2013
 mtime: 0x513a50e5:d4e448f0 -- Fri Mar  8 21:58:13 2013
crtime: 0x513a259a:35191a3c -- Fri Mar  8 18:53:30 2013

Lệnh này có thể mất một chút thời gian để trở lại, có thể vì nó cũng liệt kê mọi phạm vi liên quan đến tệp.

Bây giờ nếu bạn muốn order tệp theo ngày tạo, tôi đoán điều này không dễ dàng (cũng không đúng) có thể. Như Gilles nói, có lẽ sẽ dễ dàng hơn nếu bạn sử dụng hệ thống kiểm soát sửa đổi. Nhưng bạn có thể thử nhìn vào ext4 API ...

Tôi đã thử stat -c '%w' myfile lệnh trên một ext4 filesytem trên hệ thống Ubuntu (đủ gần đây) nhưng không thành công (nó chỉ trả lời -).

17
Totor

Đây là tập lệnh Perl sử dụng câu trả lời của Totor để đạt được điều bạn muốn (nếu hệ thống tập tin của bạn là ext4).

Hoạt động trên máy chủ của tôi (Ubuntu) và máy chủ của tôi (CentOS), nhưng không được thử nghiệm ngoài điều đó, vì vậy ymmv.

#!/usr/bin/env Perl

use Modern::Perl '2009';

use DateTime;


# Open the current directory for reading
opendir my $dh, "." or die "Unable to open directory: $!";

# Create a hash to save results into
my %results;
my %datestamp;

# Loop through the directory getting creation date stats for each file
while ( my $filename = readdir $dh ) {
    # Skip non-files
    next if $filename eq '.' or $filename eq '..';

    # Save the ls output for this file/directory
    $results{ $filename } = `ls -ld $filename`;

    my $stats = `debugfs -R 'stat $filename' /dev/sda6 2>/dev/null`;
    # crtime: 0x51cd731c:926999ec -- Fri Jun 28 12:27:24 2013
    $stats =~ m/crtime\: \w+\:\w+ -- (.+?)\n/s;
    my $datestring = $1;

    # Dissect date with a regexp, ick
    my %months = (
        'Jan' => '1',
        'Feb' => '2',
        'Mar' => '3',
        'Apr' => '4',
        'May' => '5',
        'Jun' => '6',
        'Jul' => '7',
        'Aug' => '8',
        'Sep' => '9',
        'Oct' => '10',
        'Nov' => '11',
        'Dec' => '12',
    );
    $datestring =~ m/\w+ (\w+)  ?(\d+) (\d\d)\:(\d\d)\:(\d\d) (\d\d\d\d)/;

    # Convert date into a more useful format
    my $dt = DateTime->new(
        year   => $6,
        month  => $months{$1},
        day    => $2,
        hour   => $3,
        minute => $4,
        second => $5,
    );

    # Save the datestamp for this result
    $datestamp{ $filename } = $dt->iso8601;
}

# Output in date order
my @filenames = sort { $datestamp{$a} gt $datestamp{$b} } keys %datestamp;

foreach my $filename ( @filenames ) {
    print $results{ $filename };
}
4
Denny

Sử dụng lệnh này ls -lct để sắp xếp các tệp theo ngày tạo.

2
Rohit Gaikwad

Trên các hệ thống Linux chạy kernel 4.11 trở lên, với glibc 2.28 trở lên và coreutils 8.31 trở lên , stat có thể hiển thị tệp Thời gian sinh ra trên các hệ thống tệp lưu trữ nó. Đầu ra tương tự như của ls -l có thể thu được với

stat -c "%A %4h %U %G %10s %.16w %n" *

và sắp xếp đầu ra với

stat -c "%W %A %4h %U %G %10s %.16w %n" * | sort -k1,1n | cut -d\  -f2-

Điều này sử dụng các tùy chọn định dạng này :

  • %W: thời gian sinh, tính bằng giây kể từ Unix Epoch
  • %A: loại tệp và quyền, trong ls -l định dạng
  • %4h: số lượng liên kết cứng đến tệp, được căn chỉnh thành bốn ký tự
  • %U: tên người dùng sở hữu
  • %G: tên nhóm sở hữu
  • %10s: kích thước tệp, được căn chỉnh thành mười ký tự
  • %.16w: giờ sinh, ở định dạng có thể đọc được của con người, được cắt ngắn thành mười sáu ký tự (đủ để hiển thị năm, tháng, ngày, giờ, phút và giây)
  • %n: tên tập tin
1
Stephen Kitt

Để làm điều đó trong Shell. Tôi không cung cấp thời gian sáng tạo mà thay đổi thời gian. Chỉ gỡ lỗi mới có thể hiển thị thời gian tạo nếu phân vùng là ext4

disk=$(df -Th . | grep ext4  |awk '{print $1}')
for file in "."/*
do
    inode=$(ls -i $file | awk '{print $1}')
    crtime=$(debugfs -R "stat <$inode>" $disk 2>/dev/null | grep crtime |  awk -F'-- ' '{print $2}' | awk '{print $2,$3,$5,$4}')

    printf "$crtime\t$file\n"
done | sort -k4 | sort -n -k 3 -k 1M -k2 -k4
0
luigi9876