変更された日付で最新のファイルを見つける


39

サブディレクトリを含む(大きな)ディレクトリで最新のファイル(mtime)を検索したい場合、どうすればよいですか?

私が見つけた多くの投稿は、いくつかのバリエーションをls -lt | head提案してls -ltr | tailいます(面白いことに、多くは同じですが効率が低いことを示唆しています)。

それからまた、できます

find . -type f -exec ls -lt \{\} \+ | head

1つのコマンドで指定できる限り多くのファイルに対して確実にトリックを実行します。つまり、大きなディレクトリがある場合は、-exec...\+個別のコマンドを発行します。したがって、各グループはlsそれ自体内でソートされますが、セット全体ではソートされません。したがって、ヘッドは最初のバッチの最後のエントリを取得します。

答えはありますか?


ところで、これらのすべてのバックスラッシュは必要ありません。
エンゾチブ

@enzotib:する(\ +)、そうでなければ得るfind: missing argument to '-exec'
手配

@arrange:には+意味がないためbash、このエラーはありませんので、エスケープする必要はありません。
エンゾチブ

@enzotib:あなたは正しい、私の間違い、ごめんなさい
手配

回答:


46

アクションを介して必要なことをすべて実行できるlsため、外部コマンド(as )に再帰する必要はありません。find-printf

find /path -printf '%T+ %p\n' | sort -r | head

1
ええ、私は思いつきましたfind . -type f -exec stat --format=%y \{\} \+ | sort -r | head -n1が、あなたの解決策ははるかにきれいです!
リッチ

3
追加は、| cut -d ' ' -f2ファイル名のみを取得する
QWR

出力をカリングしてhead、特定の行数を含めることもできます。最初の行だけが必要だったので、次を使用しましたhead -n 1
Timmah

8

今日も同様の問題がありましたが、なしで攻撃しましたfindsshホームディレクトリで最後に編集したファイルを返すために、実行可能な短いものが必要でした。これは私が思いついたものです。

ls -tp | grep -v /$ | head -1

-pオプションは、lsディレクトリの末尾にスラッシュ、追加grep -vスラッシュで終わる削除しライン(別名、すべてのディレクトリ)、およびhead -1単一のファイルへの出力を制限します。

これはfind、ファイル名だけを返す場合に使用する場合よりもはるかに冗長です。


これはサブディレクトリを処理しません。
クレメント

4

これは、より速くよりも私のシステムでありprintf、私は理由を理解していないものの、

find /path -type f -exec stat -c "%y %n" {} + | sort -r | head

私は確認します、より速いです。
-enzotib

もう1つ... | sort -r | head -n1 | cut -d " " -f 4-、ファイル名のみを取得する場合。
林果皞

sort -r複数の行にわたるファイル名が存在する場合、私はちょうど間違っていることがわかりました。
林果皞

2

編集:この投稿は、私が思ったほど「特に有用ではない」とは思いません。これは、ファイルのリスト全体をソートするのではなく、最後に変更されたファイルを追跡するだけの非常に高速なソリューションです。

find . -type f -printf '%T@ %p\n' | awk 'BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' '

わかりやすくするために複数の行に分散します。次のようになります。

find . -type f -printf '%T@ %p\n' | awk '
    BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; }
    {
        if ($1 > mostrecenttime)
            { mostrecenttime = $1; mostrecentline = $0; }
    }
    END { print mostrecentline; }' | cut -f2- -d ' '

編集の終わり


特に有用な投稿ではありませんが、「アレンジ」が速度について議論しているので、これを共有すると思いました。

ArrangeおよびEnzotibのソリューションでは、ディレクトリ内のすべてのファイルをmtimesでリストしてからソートします。ご存じのとおり、最大値を見つけるためにソートは必要ありません。最大値の検索は線形時間で実行できますが、ソートにはn log(n)時間かかります[違いはそれほど多くないが、それでも;)]。これをうまく実装する方法は考えられません。[編集:きれいな(ただし汚い見た目)で高速な実装が上記で提供されています。

次善策-ディレクトリ内で最後に編集されたファイルを見つけるには、各レベル1サブディレクトリで最後に編集されたファイルを再帰的に見つけます。このファイルがサブディレクトリを表すようにします。ここで、レベル1のサブディレクトリの代表とともにレベル1のファイルを並べ替えます。各ディレクトリのレベル1ファイルとサブディレクトリの数がほぼ一定の場合、このプロセスはファイルの合計数に比例してスケーリングする必要があります。

これは私がこれを実装するために思いついたものです:

findrecent() { { find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1; }
findrecent .

これを走らせて find: findrecent: No such file or directoryエラー。理由:findの-execが別のシェルで実行されます。.bashrc、.xsessionrcでfindrecentを定義しようとしましたが、助けにはなりませんでした[ここで助けていただければ幸いです]。最後に私はパッティングに頼った

#!/bin/bash
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

findrecentPATHで呼び出されたスクリプトで実行します。

私はこれを実行し、何も出力せずに待ち続けました。ただ、無限ループを処理していないことを確認するために、ファイルを

#!/bin/bash
echo "$1" >&2
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

そして再試行しました。うまくいきましたが、私のホームフォルダでは1分35秒かかりましたが、arrangeとenzotibのソリューションはそれぞれ1.69、1.95秒かかりました!

O(n)のO(n log(n))に対する優位性はこれだけです!くそー関数呼び出しのオーバーヘッド![むしろ、スクリプト呼び出しのオーバーヘッド]

しかし、このスクリプトは以前のソリューションよりも優れた拡張性を備えており、Googleのメモリバンクで実行するよりも速く実行されるに違いありません; D


2

perlconjonctinでの使用find

 find my_directory -type f -printf '%T@\t%p\n' | perl -ane '@m=@F if ($F[0]>$m[0]); END{print $m[1];}'

最もエポック==が最後に変更されたファイルの名前を取得します。


1

ファッショナブルではありませんが、Midnight Commanderでこれを実現することも可能ですです。*を検索し、結果をパネル化し、変更時刻を逆順に並べ替えます。

明らかに、find922000個のファイルを含む私のホームディレクトリは、5 mcfind未満で約14分で並べ替えられましたが、いくつかの利点があります。

  • おそらく、適切な検索呼び出しを発明するための9分の差よりも長い時間を費やすことになるでしょう。

  • エラーの可能性が低い(ソートなどに-rを指定するのを忘れた-もう一度開始)

  • ソート順などを変更することで結果セットを再生することができます-ファイルを再クエリすることなく。

  • 結果セットの一部のファイルに対してのみファイル操作を実行できます。つまり、サイズでソートし、不要ないくつかの大きなファイルを削除します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.