web-dev-qa-db-ja.com

lsを実行し、作成した日付で結果を並べ替えるにはどうすればよいですか?

日付はどの順序で並べられていますか?確かに英数字順ではありません。

ls -lt変更時刻でソートします。しかし、作成時間は必要です。

124
InquilineKea

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

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

ctimels -lcはファイル作成時刻ではありません、それは inode 変更時刻です。 iノード変更時間は、ファイルが変更されたとき(コンテンツまたはメタデータ)が変更されるたびに更新されます。特に、mtimeが将来の日付に明示的に設定されていない限り、ctimeは常にmtime(ファイル内容変更時刻)よりも新しいものです。

残念ながら、stat(2) AP​​Iはファイルの作成時間を取得する方法を提供していません。Unix標準では 必須ではありません です。

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

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

ext4を使用すると、crtime not ctime!)に言及したようなものが表示されます。

 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

このコマンドは、おそらくファイルに関連するすべてのエクステントもリストするため、戻るのにしばらく時間がかかる場合があります。

order ファイルを作成日で並べ替える場合、これは簡単に(または適切に)実行できないと思います。 Gilles が言うように、リビジョン管理システムを使用する方がおそらく簡単でしょう。ただし、ext4 AP​​Iを確認してみてください...

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

17
Totor

これは、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 };
}
4
Denny

このコマンドを使用してくださいls -lct作成日に従ってファイルをソートします。

2
Rohit Gaikwad

カーネル4.11以降、glibc 2.28以降、および coreutils 8.31以降 を実行しているLinuxシステムでは、statは、ファイルを保存するファイルシステムでのファイルの誕生時間を表示できます。 ls -lと同様の出力は、

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

とソートされた出力

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

これは これらのフォーマットオプション を使用します。

  • %W:Unixエポックからの経過時間(秒)
  • %Als -l形式のファイルタイプと権限
  • %4h:ファイルへのハードリンクの数。4文字に揃えられます。
  • %U:所有ユーザーの名前
  • %G:所有グループの名前
  • %10s:10文字に揃えられたファイルサイズ
  • %.16w:人間が読める形式で、16文字に切り捨てられた誕生年(年、月、日、時、分、秒を示すのに十分)
  • %n:ファイルの名前
1
Stephen Kitt

シェルでそれを行うには。 lsは作成時間を提供しませんが、変更時間を提供します。パーティションがext4の場合、debugfsのみが作成時間を表示できます

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