ฉันจะทำ ls แล้วเรียงลำดับผลลัพธ์ตามวันที่สร้างได้อย่างไร


112

วันที่สั่งซื้อจะเรียงลำดับตามอะไร ลำดับตัวอักษรและตัวเลขไม่แน่นอน

ls -ltเรียงลำดับตามเวลาที่แก้ไข แต่ฉันต้องการเวลาในการสร้าง



1
มีไม่ดูเหมือนจะเป็นวิธีการที่จะได้รับเวลาการสร้างแฟ้มในลินุกซ์หากไฟล์ที่อยู่บนระบบไฟล์ ext4 ดู: unix.stackexchange.com/a/131347/182996
kaartic

คำตอบ:


94

Unices ส่วนใหญ่ไม่มีแนวคิดเรื่องเวลาในการสร้างไฟล์ คุณไม่สามารถlsพิมพ์ได้เนื่องจากไม่มีการบันทึกข้อมูล หากคุณต้องการเวลาในการสร้างใช้ระบบควบคุมเวอร์ชัน : กำหนดเวลาการสร้างเป็นเวลาเช็คอิน

หากตัวแปร unix ของคุณมีเวลาสร้างให้ดูที่เอกสารของมัน ตัวอย่างเช่นในMac OS X (ตัวอย่างเดียวที่ฉันรู้of¹) ls -tUการใช้งาน Windows ยังเก็บเวลาในการสร้าง แต่ก็ไม่ได้เปิดรับพอร์ตยูทิลิตี้ของยูนิกซ์เสมอไปตัวอย่างเช่น Cygwin lsไม่มีตัวเลือกในการแสดง statยูทิลิตี้สามารถแสดงเวลาการสร้างเรียกว่า“เวลาเกิด” ได้ในสาธารณูปโภค GNU ดังนั้นภายใต้ Cygwin stat -c '%W %n' * | sort -k1nคุณสามารถแสดงไฟล์เรียงตามเวลาที่เกิดกับ

โปรดทราบว่าctime ( ls -lc) ไม่ใช่เวลาสร้างไฟล์มันเป็นเวลาเปลี่ยนinode เวลาเปลี่ยนแปลง inode นั้นจะได้รับการอัพเดตทุกครั้งที่มีอะไรเกี่ยวกับการเปลี่ยนแปลงของไฟล์ (เนื้อหาหรือข้อมูลเมตา) ยกเว้นว่าเวลาจะไม่ได้รับการอัพเดตเมื่ออ่านไฟล์เพียงอย่างเดียว โดยเฉพาะอย่างยิ่ง ctime มักจะล่าสุดกว่า mtime (เวลาแก้ไขเนื้อหาไฟล์) เว้นแต่ว่า mtime จะถูกตั้งค่าเป็นวันที่ในอนาคตอย่างชัดเจน


1
ในCygwinls -cมันเป็น ls --helpแสดงให้เห็นถึงสิ่งที่-cไม่เมื่อรวมกับและ-l -lt
Aaron D. Marasco

6
@ Aaron ไม่ ctime ไม่ใช่เวลาสร้าง มันเป็นความสับสนที่เกิดขึ้นทั่วไปโดยแท้จากข้อเท็จจริงที่ว่า "เวลา" และ "การสร้าง" เริ่มต้นด้วยตัวอักษรเดียวกัน แต่ไม่มีความสัมพันธ์ระหว่างเวลาและเวลาการสร้าง ฉันได้อัปเดตคำตอบเพื่อแก้ไขความสับสนนี้แล้ว
Gilles

ฮ่า ๆ ฉันไม่ดี ฉันพยายามยืนยันส่วน Cygwin สำหรับยา (IIRC โพสต์ต้นฉบับของคุณมีคำสั่งที่เป็นไปได้) มันบอกเป็นพิเศษว่า "ctime (เวลาของการแก้ไขข้อมูลสถานะไฟล์ล่าสุด)" ถ้าฉันให้ความสนใจ
Aaron D. Marasco

กำลังเพิ่มคำตอบ @Gilles; ฉันใช้เซิร์ฟเวอร์ไฟล์ NFS 3.x (ไม่แน่ใจในระบบไฟล์พื้นฐานเพราะเป็น UFS หรือ ZFS แม้ว่าฉันจะคาดเดา UFS) ภายใต้ Redhat 6.x: -Uเรียงลำดับตามเวลาที่สร้าง ภายใต้ระบบปฏิบัติการ Solaris 10.x: /usr/bin/lsไม่สนับสนุน-U, /usr/ucb/lsการสนับสนุน-Uและไม่เรียงลำดับตามเวลาที่สร้าง ผลลัพธ์เหล่านี้ขึ้นอยู่กับระบบไฟล์ที่จัดเก็บข้อมูลนั้นตั้งแต่แรก
Brian Vandenberg

1
@ghoti หากไม่มีไฟล์ใดที่ถูกลบ (หรือย้าย / เปลี่ยนชื่อ / hardlinked / …) ในไดเรกทอรีลำดับของไดเรกทอรีคือลำดับการสร้างในบางระบบไฟล์ แต่ไม่ใช่ทั้งหมด นั่นไม่ใช่ความจริงใน ext4 เช่น ฉันไม่รู้ว่ามันเป็นจริงใน UFS ของ Solaris หรือไม่
Gilles

16

น่าเสียดายที่stat(2)API ไม่ได้มีวิธีในการรับเวลาในการสร้างไฟล์เนื่องจากไม่จำเป็นต้องใช้ตามมาตรฐาน Unix

อย่างไรก็ตามระบบไฟล์บางระบบext4จะบันทึกข้อมูลนี้ไว้ในเมทาดาทาของไฟล์ ไม่มีวิธีมาตรฐานในการรับ แต่มีวิธี ( extระบบไฟล์เท่านั้น):

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

คุณจะได้รับสิ่งที่ต้องการการกล่าวขวัญว่าcrtime( ไม่ ctime ) 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

คำสั่งนี้อาจใช้เวลาสักครู่เพื่อส่งคืนอาจเป็นเพราะมันยังแสดงรายการทุกส่วนที่เกี่ยวข้องกับไฟล์

ตอนนี้ถ้าคุณต้องการสั่งซื้อไฟล์ตามวันที่สร้างฉันคิดว่ามันเป็นไปไม่ได้อย่างง่ายดาย อย่างที่กิลส์บอกว่าอาจจะง่ายกว่าถ้าคุณใช้ระบบควบคุมการแก้ไข แต่คุณอาจลองดูที่ext4API ...

ฉันลองใช้stat -c '%w' myfileคำสั่งบนext4filesytem บนระบบ Ubuntu (ไม่นานมานี้) โดยไม่ประสบความสำเร็จ (เป็นเพียงคำตอบ-)


หากใครต้องการสายการบินเดียว:f='/path/to/file'; debugfs -R "stat $f" $(df $f|(read a; read a b; echo "$a"))|grep crtime
Boop

3

นี่คือสคริปต์ Perl ที่ใช้คำตอบของ Totor เพื่อให้ได้สิ่งที่คุณต้องการ (ถ้าระบบไฟล์ของคุณมี ext4)

ทำงานบนเครื่องที่บ้านของฉัน (Ubuntu) และเซิร์ฟเวอร์ของฉัน (CentOS) แต่ไม่ได้ทดสอบมากกว่านั้นดังนั้น 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 };
}

นอกจากนี้ยังกล่าวถึงว่าบางไฟล์อาจมีข้อมูลเมตา (เช่น exif) ซึ่งบันทึกวันที่ / เวลาที่สร้าง หากไฟล์ทั้งหมดของคุณเป็นรูปถ่ายดิจิทัลคุณน่าจะมีข้อมูลนี้เป็นส่วนใหญ่ นี่คือตัวอย่างการใช้ภาพของ Perl :: ExifTool
Jonathan Cross

0

ใช้คำสั่งนี้ls -lctเพื่อเรียงลำดับไฟล์ตามวันที่สร้าง


2
yup ที่ไม่ใช่คำสั่ง "ถูกต้อง" แต่มันเป็นสิ่งที่คุณกำลังมองหาในกรณีส่วนใหญ่
madnight

มีวิธีทำด้วย "ค้นหา" เพื่อให้พิมพ์ไฟล์ทั้งหมดในไดเรกทอรีย่อยด้วยวิธีนี้หรือไม่
โคลิน D

ctimeเป็นเวลาที่เปลี่ยนแปลงและไม่สร้างเวลา
Nabi KAZ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.