Jak zrobić ls, a następnie posortować wyniki według daty utworzenia?

112

W jakiej kolejności są uporządkowane daty? Na pewno nie porządek alfanumeryczny.

ls -ltsortuje według czasu modyfikacji. Ale potrzebuję czasu na stworzenie.

InquilineKea
źródło
1
Tam nie wydaje się być sposób, aby uzyskać czas tworzenia plików w Linuksie, jeśli plik znajduje się na systemie plików ext4. Zobacz: unix.stackexchange.com/a/131347/182996
kaartic

Odpowiedzi:

94

Większość jednorożców nie ma pojęcia czasu tworzenia pliku. Nie można lsgo wydrukować, ponieważ informacje nie są rejestrowane. Jeśli potrzebujesz czasu utworzenia, skorzystaj z systemu kontroli wersji : zdefiniuj czas utworzenia jako czas zameldowania.

Jeśli twój wariant unixa ma czas na stworzenie, spójrz na jego dokumentację. Na przykład w Mac OS X (jedynym znanym mi przykładzie) użyj ls -tU. Windows przechowuje również czas utworzenia, ale nie zawsze jest narażony na porty narzędzi uniksowych, na przykład Cygwin lsnie ma opcji, aby to pokazać. statNarzędzie może pokazać czas tworzenia, zwany „czas narodzin” w narzędzia GNU, więc pod Cygwin można pokazać pliki posortowane według czasu urodzenia z stat -c '%W %n' * | sort -k1n.

Zauważ, że ctime ( ls -lc) to nie czas tworzenia pliku , to czas zmiany i- węzła . Czas zmiany i-węzła jest aktualizowany za każdym razem, gdy cokolwiek zmienia się w pliku (zawartość lub metadane), z wyjątkiem tego, że ctime nie jest aktualizowany, gdy plik jest tylko odczytywany (nawet jeśli atime jest aktualizowany). W szczególności ctime jest zawsze nowszy niż mtime (czas modyfikacji zawartości pliku), chyba że mtime został wyraźnie ustawiony na datę w przyszłości.

Gilles
źródło
1
W Cygwin tak jest ls -c. ls --helppokazuje, co -crobi w połączeniu z -li -lt.
Aaron D. Marasco,
6
@Aaron Nie, ctime nie jest czasem tworzenia. Jest to powszechne zamieszanie oparte wyłącznie na fakcie, że „ctime” i „kreacja” zaczynają się od tej samej litery, ale nie ma związku między ctime a czasem stworzenia. Zaktualizowałem swoją odpowiedź, aby rozwiązać ten problem.
Gilles
LOL mój zły. Próbowałem potwierdzić dla ciebie część Cygwin (IIRC twój oryginalny post miał możliwe polecenie). Mówi konkretnie „ctime (czas ostatniej modyfikacji informacji o statusie pliku)”, jeśli zwracam uwagę.
Aaron D. Marasco,
Dodanie do odpowiedzi @Gilles; Korzystam z serwera plików NFS 3.x (niepewny co do bazowego systemu plików; jest to albo UFS, albo ZFS, choć chyba UFS). Pod Redhat 6.x: -Usortuje według czasu utworzenia. W systemie Solaris 10.x: /usr/bin/lsnie obsługuje -U, /usr/ucb/lsobsługuje -Ui sortuje według czasu utworzenia. Te wyniki oczywiście zależą przede wszystkim od systemu plików przechowującego te informacje.
Brian Vandenberg,
1
@ghoti Jeśli żadne pliki nie zostały nigdy usunięte (lub przeniesione / przemianowane / hardlinkowane /…) w katalogu, kolejność katalogów to kolejność tworzenia w niektórych systemach plików, ale nie we wszystkich. Na przykład nie jest to prawdą w przypadku ext4. Nie wiem, czy to prawda w systemie UFS Solaris.
Gilles
16

Niestety stat(2)interfejs API nie pozwala uzyskać czasu na utworzenie pliku, ponieważ nie jest to wymagane przez standardy uniksowe.

Jednak niektóre systemy plików, ponieważ ext4, zapisują te informacje w obrębie metadanych plików. Po prostu nie ma standardowego sposobu na zdobycie go, ale istnieje sposób ( exttylko systemy plików):

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

Otrzymasz coś takiego, wspominając crtime( nie ctime !), Jeśli użyjesz 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

To polecenie może zająć trochę czasu, prawdopodobnie dlatego, że wyświetla również wszystkie zakresy związane z plikiem.

Teraz, jeśli chcesz zamówić pliki według daty utworzenia, myślę, że nie jest to łatwe (ani właściwie) możliwe. Jak mówi Gilles , prawdopodobnie byłoby łatwiej, gdybyś użył systemu kontroli wersji. Ale możesz spróbować spojrzeć na ext4API ...

Próbowałem wykonać stat -c '%w' myfilepolecenie na systemie ext4plików w (dość nowym) systemie Ubuntu bez powodzenia (po prostu odpowiada -).

Totor
źródło
Jeśli ktoś chce jednego liniowca:f='/path/to/file'; debugfs -R "stat $f" $(df $f|(read a; read a b; echo "$a"))|grep crtime
Boop
3

Oto skrypt Perla, który używa odpowiedzi Totora, aby osiągnąć to, czego chcesz (jeśli twój system plików to ext4).

Działa na moim komputerze domowym (Ubuntu) i moim serwerze (CentOS), ale nie został przetestowany poza tym, więc 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
źródło
Warto również wspomnieć, że niektóre pliki mogą mieć metadane (takie jak exif), które rejestrują datę / godzinę utworzenia. Jeśli na przykład wszystkie Twoje pliki są zdjęciami cyfrowymi, najprawdopodobniej masz te dane. Oto przykład z użyciem Image :: ExifTool w perlu .
Jonathan Cross
0

Użyj tego polecenia, ls -lctaby posortować pliki według daty utworzenia.

Rohit Gaikwad
źródło
2
tak, to nie jest „poprawne” polecenie, ale w większości przypadków jest to to, czego szukasz
szaleństwo
czy można to zrobić za pomocą polecenia „znajdź”, aby w ten sposób drukować wszystkie pliki w podkatalogach?
Colin D
Jest ctimeto czas zmiany, a nie tworzenie czasu.
Nabi KAZ