ls を実行し、生成日ごとに結果をソートするにはどうすればよいですか?

ls を実行し、生成日ごとに結果をソートするにはどうすればよいですか?

日付はどの順序でソートされますか?もちろん英数字の順序ではありません。

ls -lt修正時間で並べ替えます。しかし、創造的な時間が必要です。

答え1

ほとんどのUnixにはファイル作成時間の概念はありません。ls情報が記録されていないため印刷できません。作成時間が必要な場合バージョン管理システム:生成時間をチェックイン時間として定義します。

UNIXバリアントに作成日がある場合は、そのマニュアルを確認してください。例えば、Mac OS X(私が知っている唯一の例)ls -tU.Windowsでは、作成時間も保存されますが、Unixユーティリティポートに常に公開されるわけではありません。たとえば、Cygwinにはlsそれを表示するオプションはありません。このstatユーティリティは、GNUユーティリティで「生成時間」と呼ばれる生成時間を表示できるため、Cygwinではstat -c '%W %n' * | sort -k1n

気づく時間( ls -lc)ファイル作成時間ではありません、これはインデックスノード時間を変更してください。ファイル(コンテンツまたはメタデータ)に変更があるたびにinodeの変更時間が更新されますが、ファイルを読み取るだけでctimeは更新されません(atimeが更新されても)。特に、mtimeが明示的に将来の日付に設定されていない限り、ctimeは常にmtime(ファイルの内容が変更された時刻)よりも最新です。

答え2

残念ながらstat(2)、APIはファイル作成時間を取得する方法を提供しません。不要Unix標準によると。

ただし、一部のファイルシステム(たとえば、ext4またはXFS)はこの情報をファイルメタデータに保持します。それを得るための標準的な方法はありませんが、方法はあります:

注:この回答は主にLinuxシステムに関連しています。

アップデート2021:新しいlsコマンドオプション

~によるとスティーブン・チャジェラスlscoreutils 8.32バージョン(glibc 2.28およびカーネル4.11を含む)は、新しいstatx(2)システムコール(この回答の終わりを参照)を使用して生成時間メタデータを抽出できるようになりました。

だからファイルをリストするにはソート済み作成/生年月日/時間に応じて、次のものを使用できます。

ls -lt --time=birth

この-tオプションは、オプションに示されている時間タイプによってソートされます--time(I疑う birth必要に応じて変更できますcreation。)

-rソート順序を逆にするために追加されました。

debugfsextNファイルシステムの場合

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

このコマンドはファイルに関連するすべての範囲を一覧表示するため、返すのに多少時間がかかることがあります。

VCSを使用していますか?

今あなたが望むなら注文するファイルは作成日ごとにソートされていますが、達成するのは簡単でも正確でもないようです。 〜のようにザイルズバージョン管理システムを使用すると、簡単にすることもできます。しかし、ext4APIを試してみることはできます。

司令部stat(2021年アップデート)

(最近)Ubuntuシステムのファイルシステムでコマンドを試みましたが、stat -c '%w' myfile成功しませんでした(応答したばかりです)。ext4-

2021年アップデート:~によるとトーマス・ニーマン、上記のコマンドは、少なくともcoreutils 8.31、glibc 2.28、およびカーネル4.11がある場合はLinuxで動作します。次のことを試すことはできますが、ファイル自体はソートされません。

stat -c '%w %n' * | sort -n 

これを達成するために。%W人が読める日付に興味がない場合は使用してください。逆順-rにするオプションが追加されました。sort


2020年アップデート:Linuxベースカーネル 4.11、新しいstatx(2)システムコール紹介されました。これらのAPIは、ファイルシステムで情報が利用可能な場合は、ファイル作成時間にアクセスできます。私が知る限り、この情報を得るための標準/安定したユーザースペースユーティリティはありませんが、いつか出てくることができます。これは標準のPOSIXインターフェイスではなく、Linux専用インターフェイスです。これman:

statx()はLinuxカーネル4.11に追加され、ライブラリサポートはglibc 2.28に追加されました。

statx() は Linux 専用です。

答え3

カーネル 4.11 以降、glibc 2.28 以降を実行する Linux システムでcoreutils 8.31以降statファイルが保存されているファイルシステムのファイル作成時間を表示します。ls -l同様の出力は、次のように取得できます。

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

並べ替えられた出力(改行文字を含むファイル名がないと仮定)

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

そしてcoreutils 8.32以降、次のオプションをls使用して、出生時間に基づいて表示および並べ替えることができます。--time=birth

ls -l --time=birth

上記の呼び出しstatこれらの書式設定オプション:

  • %.10W:出生時間、Unix時代以降の秒(小数点10桁)。
  • %A: ファイル形式と権限、ls -l形式
  • %4h:4文字でソートされたファイルへのハードリンク数
  • %U: それが属するユーザーの名前
  • %G:所属するグループの名前
  • %10s:ファイルサイズ、10文字でソート
  • %.16w:生年月日、人が読める形式、16文字で切り捨て(年、月、日、時、分、秒を表示するのに十分)
  • %n: ファイル名

答え4

以下は、あなたが望むことを達成するためにTotorの答えを使用するPerlスクリプトです(ファイルシステムが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 };
}

関連情報