web-dev-qa-db-ja.com

最後にファイルを開いたとき

ファイルが最後に開かれた時間を取得し、それらの時間でディレクトリ内のすべてのファイルをソートすることは可能ですか?

101
student

これは、「開いた」という意味に依存しますが、一般的にはそうです。通常記録される3つのタイムスタンプがあります。

  • mtime —ファイルの内容が変更されると更新されます。これは、ほとんどの場合、「デフォルト」のファイル時間です。
  • ctime —ファイルorのメタデータ(所有者、権限)が変更されると更新されます
  • atime —ファイルが読み込まれたときに更新されます

したがって、一般的に見たいのはファイルのatimeです。 statまたはlsを使用して取得できます。 ls -luを使用してこれを行うことができますが、私はls -l --time=atime(ほとんどすべての最新のLinuxディストリビューションでサポートされているはずです)を使用することを好んでいます。それは良いです。そしてsortまでに、-tフラグをlsに追加します。さあ、行きます。

ただし、大きな注意点があります。ファイルが読み込まれるたびにatimeを更新すると、通常は不要なIOが大量に発生し、すべてが遅くなります。そのため、ほとんどのLinuxディストリビューションでは、デフォルトでnoatimeファイルシステムマウントオプションがデフォルトで使用され、基本的には何度も強制終了されます。または、relatimeは、制限が経過したときに(通常は1日1回)、または前回の読み取り以降にファイルが実際に変更された場合にのみ更新されます。これらのオプションがアクティブかどうかは、mountコマンドを実行して確認できます。

また、アクセス時間はファイル名ではなくiノードによって決まるため、ハードリンクがある場合、ハードリンクを読み取ると、同じファイルを参照するすべての名前が更新されます。

また、cは「作成」ではないことに注意してください。作成はUnix/Linuxファイルシステムでは追跡されません。これは奇妙に見えますが、実際には理にかなっています。ファイルシステムがオリジナルかどうかを知る方法がないためです。ファイルは40年前に作成され、ここにコピーされた可能性があります。そして実際、多くのファイルエディターはオリジナルの上にコピーを作成することで機能します。その情報が必要な場合は、gitのようなバージョン管理システムを使用するのが最善です。

182
mattdm

ls -ltuすべてのファイルを一覧表示し、アクセス時間で表示およびソートします。

man lsから:

-u     with -lt: sort by, and show, access time with -l: show access
       time and sort by name otherwise: sort by access time
21
Shawn J. Goff

これにはfindコマンドが最適です。 -ctime-mtime-atimeオプション

4
GBH

リストが人間が使用するものである場合は、lsを日付ソートフラグの1つ(アクセス(読み取り)時間の場合は_-tu_、変更(書き込み)時間の場合は_-t_のみ、または_-tc_(inode変更時間)。詳細については mattdm's answer を参照してください(特に_-a_および_-c_の定義に関する警告)。

これがプログラムの消費のためである場合、 lsの出力の解析は問題があります です。シェルがzshの場合は、とにかくlsは必要ありません。zshには、アクセスの増加(*(Oa))、inode変更(*(Oc) )または変更(*(Om))時間。小文字oは、年齢の昇順で並べ替えます。

_act_on_files_by_date *(Om)
_

それ以外の場合、ファイル名に改行文字や印刷できない文字(現在のロケール)が含まれていないことがわかっている場合は、次のようにすることができます。

_ls -t | while read -r name; do act_on_one_file "$name"; done
ls -t | xargs -I {} act_on_one_file {}
_

一度に多くのファイルに対してコマンドを呼び出す場合は、さらに設定が必要です。 act_on_files_by_date $(ls -t)は、このように機能しないことに注意してください。ワイルドカード文字または空白を含むファイル名は、コマンド置換の結果として展開されるためです。次のコードは、ファイル名に改行または印刷できない文字が含まれていない限り機能します。

_IFS='
'
set -f
act_on_files_by_date $(ls -t)
set +f
unset IFS
_

任意のファイル名に対応したい場合は、標準のシェルより強力なツール(zsh、Perl、python…)を使用しないと、非常に苦労します。