Bagaimana cara melakukan ls lalu mengurutkan hasil berdasarkan tanggal yang dibuat?

Jawaban:

94

Sebagian besar unices tidak memiliki konsep waktu pembuatan file. Anda tidak dapat lsmencetaknya karena informasinya tidak direkam. Jika Anda memerlukan waktu pembuatan, gunakan sistem kontrol versi : tentukan waktu pembuatan sebagai waktu check-in.

Jika varian unix Anda memiliki waktu pembuatan, lihat dokumentasinya. Misalnya, pada Mac OS X (satu-satunya contoh yang saya tahu¹), gunakan ls -tU. Windows juga menyimpan waktu pembuatan, tetapi itu tidak selalu terkena port utilitas unix, misalnya Cygwin lstidak memiliki opsi untuk menunjukkannya. The statutilitas dapat menunjukkan waktu penciptaan, yang disebut “waktu lahir” di utilitas GNU, jadi di bawah Cygwin Anda dapat menampilkan file diurutkan berdasarkan waktu kelahiran dengan stat -c '%W %n' * | sort -k1n.

Perhatikan bahwa ctime ( ls -lc) bukan waktu pembuatan file , ini adalah waktu perubahan inode . Waktu perubahan inode diperbarui setiap kali ada sesuatu tentang perubahan file (konten atau metadata) kecuali bahwa waktu tidak diperbarui ketika file hanya dibaca (bahkan jika atime diperbarui). Secara khusus, waktu selalu lebih baru daripada waktu (waktu modifikasi konten file) kecuali waktu telah secara eksplisit diatur ke tanggal di masa depan.

Gilles
sumber
1
Dalam Cygwin itu ls -c. ls --helpmenunjukkan apa yang -cdikombinasi dengan -ldan -lt.
Aaron D. Marasco
6
@ Harun Tidak, waktunya bukan waktu pembuatan. Ini adalah kebingungan umum yang murni didasarkan pada kenyataan bahwa "waktu" dan "penciptaan" dimulai dengan huruf yang sama, tetapi tidak ada hubungan antara waktu dan waktu penciptaan. Saya telah memperbarui jawaban saya untuk mengatasi kebingungan ini.
Gilles
LOL saya yang buruk. Saya mencoba mengonfirmasi bagian Cygwin untuk Anda (IIRC pos asli Anda memiliki perintah yang memungkinkan). Itu secara khusus mengatakan "ctime (waktu modifikasi terakhir dari informasi status file)" jika saya telah memperhatikan.
Aaron D. Marasco
Menambah jawaban @Gilles; Saya menggunakan server file NFS 3.x (tidak yakin pada sistem file yang mendasarinya; itu baik UFS atau ZFS, meskipun saya menebak UFS). Di bawah Redhat 6.x: -Umengurutkan berdasarkan waktu pembuatan. Di bawah Solaris 10.x: /usr/bin/lstidak mendukung -U, /usr/ucb/lsmendukung , -Udan mengurutkan berdasarkan waktu pembuatan. Hasil ini jelas tergantung pada sistem file yang menyimpan info itu di tempat pertama.
Brian Vandenberg
1
@ghoti Jika tidak ada file yang pernah dihapus (atau dipindahkan / diubah namanya / hardlinked / ...) dalam direktori, maka urutan direktori adalah urutan pembuatan pada beberapa sistem file, tetapi tidak semua. Itu tidak benar pada ext4, misalnya. Saya tidak tahu apakah itu benar pada UFS Solaris.
Gilles
16

Sayangnya, stat(2)API tidak menyediakan cara untuk mendapatkan waktu pembuatan file, karena tidak diperlukan oleh standar Unix.

Namun, beberapa sistem file, seperti ext4, menyimpan informasi ini dalam metadatas file. Tidak ada cara standar untuk mendapatkannya, tetapi ada cara ( exthanya sistem file):

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

Anda akan mendapatkan sesuatu yang menyebutkan crtime( tidak ctime !) Jika Anda gunakan 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

Perintah ini mungkin membutuhkan waktu untuk kembali, mungkin karena ia juga mencantumkan setiap tingkat yang terkait dengan file.

Sekarang jika Anda ingin memesan file berdasarkan tanggal pembuatan, saya kira ini tidak mudah (juga tidak benar). Seperti yang dikatakan Gilles , mungkin akan lebih mudah jika Anda menggunakan sistem kontrol revisi. Tetapi Anda dapat mencoba melihat ext4API ...

Saya mencoba stat -c '%w' myfileperintah pada ext4filesytem pada sistem Ubuntu (cukup baru) tanpa hasil (hanya menjawab -).

Totor
sumber
Jika ada yang menginginkan satu liner:f='/path/to/file'; debugfs -R "stat $f" $(df $f|(read a; read a b; echo "$a"))|grep crtime
Boop
3

Berikut skrip Perl yang menggunakan jawaban Totor untuk mencapai apa yang Anda inginkan (jika filesystem Anda adalah ext4).

Bekerja pada mesin rumah saya (Ubuntu) dan server saya (CentOS), tetapi tidak diuji lebih dari itu, jadi 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 };
}
Denny
sumber
Juga bagus untuk menyebutkan bahwa beberapa file mungkin memiliki metadata (seperti exif) yang mencatat tanggal / waktu pembuatan. Jika semua file Anda adalah foto digital misalnya, kemungkinan besar Anda memiliki data ini. Berikut adalah contoh menggunakan Image perl :: ExifTool .
Jonathan Cross
0

Gunakan perintah ini ls -lctuntuk mengurutkan file sesuai tanggal pembuatan.

Rohit Gaikwad
sumber
2
ya itu bukan perintah "benar", tetapi itu adalah apa yang Anda cari dalam banyak kasus
madnight
apakah ada cara untuk melakukan ini dengan "find" sehingga ia mencetak semua file dalam subdirektori dengan cara ini?
Colin D
Itu ctimeadalah perubahan waktu, dan bukan menciptakan waktu.
Nabi KAZ