web-dev-qa-db-ja.com

Unix / Linuxが検索した日付順に並べ替え

直近の変更によって結果を並べ替える簡単なfindをどのようにしたらできますか?

これが私が使っている現在のfindです(私はPHPでシェルエスケープをしているので、それが変数の推論です):

find '$dir' -name '$str'\* -print | head -10

この順序で最近の検索をどのように変更できますか。 (注:検索後にソートしたくはありませんが、最近変更されたものに基づいて結果を見つけてください)。

124
Richard Easton

これを使って:

find . -printf "%T@ %Tc %p\n" | sort -n

man find からのprintf引数:

  • %Tkkで指定されたフォーマットのファイルの最後の修正時刻。

  • @:GMTの1970年1月1日00:00からの経過秒数、小数部.

  • c:ロケールの日時(Sat Nov 04 12:02:33 EST 1989)。

  • %p:ファイルの名前.

133
user195696

最も簡単な方法は、 glob修飾子 のおかげでzshを使うことです。

print -lr -- $dir/**/$str*(om[1,10])

GNU findがある場合は、ファイルの修正時刻を表示し、それに従ってソートします。

find -type f -printf '%T@ %p\0' |
sort -zk 1nr |
sed -z 's/^[^ ]* //' | tr '\0' '\n' | head -n 10

GNU findがあるが他のGNUユーティリティがない場合は、NULLの代わりに改行を区切り文字として使用してください。改行を含むファイル名のサポートを失うでしょう。

find -type f -printf '%T@ %p\n' |
sort -k 1nr |
sed 's/^[^ ]* //' | head -n 10

あなたがPerlを持っているなら(ここで私はファイル名に改行がないと仮定します):

find . -type f -print |
Perl -l -ne '
    $_{$_} = -M;  # store file age (mtime - now)
    END {
        $,="\n";
        @sorted = sort {$_{$a} <=> $_{$b}} keys %_;  # sort by increasing age
        print @sorted[0..9];
    }'

あなたがPythonを持っているならば(またファイル名に改行がないと仮定して):

find . -type f -print |
python -c 'import os, sys; times = {}
for f in sys.stdin.readlines(): f = f[0:-1]; times[f] = os.stat(f).st_mtime
for f in (sorted(times.iterkeys(), key=lambda f:times[f], reverse=True))[:10]: print f'

おそらくPHPで同じことをする方法がありますが、私はそれを知りません。

もしあなたがPOSIXツールだけで作業したいのなら、それはかなり複雑です。 変更日順でソートされたファイルを再帰的に一覧表示する方法(利用可能なstatコマンドはありません!) (最初の10個を見直すのは簡単です).

82
Gilles

PHPやPythonを使用する必要はありません。単に ls

man ls:
-t     sort by modification time
-r,    reverse order while sorting (--reverse )
-1     list one file per line

find /wherever/your/files/hide -type f -exec ls -1rt "{}" +;

コマンド*が失敗ステータス(つまり引数リストが長すぎる)で終了する場合、findで反復できます。言い換え: 新しいプロセスの引数の最大長

  • find . -print0|xargs -0 command(findが「-exec +」を実装せず、「-print0」を知っている場合、速度を最適化します)
  • find . -print|xargs command(引数に空白がない場合)

引数の大部分が長いパス、絶対パス、または相対パスで構成されている場合、アクションをディレクトリに移動してみてください:cd /directory/with/long/path; command *そして、別の簡単な修正方法は、一致する引数を減らすことです:command [a-e]*; command [f-m]*; ...

あなただけが必要です ls

上記のようにfind /wherever/your/files/hide -type f -exec ls -1rt "{}" +;を実行できます。

または

ls -1rt `find /wherever/your/file/hides -type f`
9
skippy1910

User195696の答えを拡張 する

find . -type f -printf "%T@\t%Tc %6k KiB %p\n" | sort -n | cut -f 2-

それぞれのファイルについて、最初に数値のタイムスタンプ(ソートのために、続いてタブ\t)、次に人間が読める形式のタイムスタンプ、次にファイルサイズ(残念ながらfind-printfはメガバイトではできず、キロバイトのみ)が出力されます相対パス.

それからsort -nは最初の数値フィールドでそれをソートします。

それからcutはユーザーにとって興味のない最初の数値フィールドを取り除きます。 (2番目のフィールド以降を印刷します。)デフォルトのフィールド区切り文字は\tまたはtabulationです。

出力例

Thu 06 Feb 2014 04:49:14 PM EST     64 KiB ./057_h2_f7_10/h2_f7_10.class
Fri 07 Feb 2014 02:08:30 AM EST 7962976 KiB ./056_h2_f7_400/h2__rh_4e-4.mph
Fri 07 Feb 2014 02:23:24 AM EST 7962976 KiB ./056_h2_f7_400/h2_f7_400_out_Model.mph
Fri 07 Feb 2014 02:23:24 AM EST      0 KiB ./056_h2_f7_400/h2_f7_400_out.mph.status
Fri 07 Feb 2014 02:23:24 AM EST     64 KiB ./056_h2_f7_400/1579678.out
Fri 07 Feb 2014 03:47:31 AM EST 8132224 KiB ./057_h2_f7_10/h2__rh_1e-5.mph
Fri 07 Feb 2014 04:00:49 AM EST 8132224 KiB ./057_h2_f7_10/h2_f7_10_out_Model.mph
Fri 07 Feb 2014 04:00:49 AM EST      0 KiB ./057_h2_f7_10/h2_f7_10_out.mph.status
Fri 07 Feb 2014 04:00:49 AM EST     64 KiB ./057_h2_f7_10/1579679.out
Fri 07 Feb 2014 09:47:18 AM EST   9280 KiB ./056_h2_f7_400/h2__rh_4e-4.mat
Fri 07 Feb 2014 10:51:23 AM EST   9728 KiB ./018_bidomain/h2_plain__rh_1e-5.mat
Fri 07 Feb 2014 10:58:33 AM EST   9568 KiB ./057_h2_f7_10/h2__rh_1e-5.mat
Fri 07 Feb 2014 05:05:38 PM EST     64 KiB ./058_h2_f7_stationary/h2_f7_stationary.Java
Fri 07 Feb 2014 06:06:29 PM EST     32 KiB ./058_h2_f7_stationary/slurm.slurm
Sat 08 Feb 2014 03:42:07 AM EST      0 KiB ./058_h2_f7_stationary/1581061.err
Sat 08 Feb 2014 03:42:14 AM EST     64 KiB ./058_h2_f7_stationary/h2_f7_stationary.class
Sat 08 Feb 2014 03:58:28 AM EST  70016 KiB ./058_h2_f7_stationary/h2s__rh_1e-5.mph
Sat 08 Feb 2014 04:12:40 AM EST  70304 KiB ./058_h2_f7_stationary/h2s__rh_4e-4.mph
Sat 08 Feb 2014 04:12:53 AM EST  70304 KiB ./058_h2_f7_stationary/h2_f7_stationary_out_Model.mph
Sat 08 Feb 2014 04:12:53 AM EST      0 KiB ./058_h2_f7_stationary/h2_f7_stationary_out.mph.status
Sat 08 Feb 2014 04:12:53 AM EST     32 KiB ./058_h2_f7_stationary/1581061.out
Mon 10 Feb 2014 11:40:54 AM EST    224 KiB ./058_h2_f7_stationary/h2s__rh_4e-4.mat
Mon 10 Feb 2014 11:42:32 AM EST    224 KiB ./058_h2_f7_stationary/h2s__rh_1e-5.mat
Mon 10 Feb 2014 11:50:08 AM EST     32 KiB ./plot_grid.m

ファイルサイズフィールドを意図的に6文字にしました。これを長くすると、ファイルのサイズを視覚的に区別するのが難しくなるためです。このように、1e6 KiBを超えるファイルは突き出します。1文字は1〜9 GBを意味し、2文字は10〜99 GBを意味します。


編集:これは別のバージョンです(find . -printf "%Tc"はMinGW/MSYSでクラッシュするので):

find . -type f -printf "%T@\t%p\n" | sort -n | cut -f 2- | xargs -I{} ls -Glath --si {}

ような出力を与える:

-rw-r--r-- 1 es 23K Jul 10  2010 ./laptop_0000071.jpg
-rw-r--r-- 1 es 43M Jul 29 19:19 ./work.xcf
-rw-r--r-- 1 es 87K Jul 29 20:11 ./patent_lamps/US Patent 274427 Maxim Lamp Holder.jpg
-rw-r--r-- 1 es 151K Jul 29 20:12 ./patent_lamps/Edison screw-in socket.png
-rw-r--r-- 1 es 50K Jul 29 20:13 ./patent_lamps/1157 Lamp.jpg
-rw-r--r-- 1 es 38K Jul 29 20:14 ./patent_lamps/US06919684-20050719-D00001.png

どこで:

  • -I{}{}の出現を引数に置き換えます。の改行は引数の区切り文字になります(上記のファイル名のスペースに注意してください)。

  • ls -Gは、グループ名の印刷を抑制します(スペースの無駄)。

  • ls -h --siは、人間が読める形式のファイルサイズを生成します(--siの方が正確です)。

  • ls -tは時間順にソートされていますが、これはここでは関係ありませんが、私が通常使用するものです。

6
Evgeni Sergeev

@ user195696の回答のOS X版です。

  1. タイムスタンプ付き:

    find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r
    
  2. タイムスタンプなし

    find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r | awk -F' ' '{ print substr($0, length($1) + 2) }'
    
3
user9399

試してください:

find '$dir' -name '$str'\* -print | xargs ls -tl | head -10

しかし、-mmin/-mtime-typeでデータをフィルタリングするのも便利です。

1
Good.Dima

あなたのfindの選択が非常に単純であるなら、あなたはそれなしでそれをすることができるかもしれない、そして単にlsを使う:

ls -1 *.cc # -r -t optional
1
djc

私は、これがMac OS X上で(そして他のUnix上でも動作するのに十分に一般的な)仕事を終わらせることを見つけた。

find . -type f -ls | awk '{print $(NF-3), $(NF-2), $(NF-1), $NF}' | sort
1
Bryan Petty

私はFreeBSD(OS X)とLinuxの両方に使える簡単な解決法を持っています。

find . -type f -exec ls -t {} +
1
Alex Shchur

つかいます:

find . -type f -mtime 0 -printf "[%TD %TI:%TM%Tp] %s %p\n" | sort -n | awk '{
    hum[1024**4]="TB"; hum[1024**3]="GB"; hum[1024**2]="MB"; hum[1024]="KB"; hum[0]="B";
    for (x=1024**4; x>=1024; x/=1024){
    if ($3>=x) { printf $1" "$2"\t%7.2f %s\t%s\n",$3/x,hum[x],$4;break }
    }}';

このコマンドはファイルを変更日順にソートします。

そして次のように表示します。

[12/05/13 03:10PM] 1.75 MB ./file.text
[12/06/13 11:52PM] 2.90 MB ./file2.mp4
[12/07/13 04:11PM] 4.88 MB ./file3.mp4
[12/07/13 09:17PM] 4.74 MB ./test.apk
1
Akash

私はfindが出力の順序を変更するオプションを持っているとは思いません。 -mtime-mminを使用すると、特定の期間内に変更されたファイルに結果を制限することができますが、出力はソートされません - それを自分で行う必要があります。 GNU findには-printfオプションがあり、とりわけ、見つかった各ファイルの変更時刻を表示できます(フォーマット文字列%tまたは%Tk)。それはあなたが望むようにfind出力をソートするのを助けるかもしれません。

0
Jim Lewis

スクリプトでファイル名の空白を正しく処理するようにして、Akashsの回答を改善しました。

find . -type f -mtime 0 -printf ";[%TD %TI:%TM%Tp];%s;%p\n" | sort -n | awk -F ";" '{
    hum[1024**4]="TB"; hum[1024**3]="GB"; hum[1024**2]="MB"; hum[1024]="KB"; hum[0]="B";
    for (x=1024**4; x>=1024; x/=1024){
    if ($3>=x) { printf $1" "$2"\t%7.2f %s\t%s\n",$3/x,hum[x],$4;break }
    }}';
0
jan

BSDとLinux(POSIXではなく)でstatを使うことができます:

$ stat -f "%m%t%N" /[the dir]/* | sort -rn | cut -f2-

数を制限したい場合

$ stat -f "%m%t%N" /[the dir]/* | sort -rn | head -[the number] | cut -f2-
0
drewk

すべてのPNGファイルを$PWDで時間順に並べたい場合は、次のようにします。

この単純なワンライナーは、findlsの正規表現のすべての柔軟性を与えます。

find $PWD -name "*.png" -print0 | xargs -0 ls -laht | less
0
john smith