Unix / Linuxの変更日による検索およびソート


138

find最後に変更された順に結果を並べるシンプルな方法はありますか?

ここにfind私が使用している電流があります(PHPでシェルエスケープをしているので、変数の理由です):

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

直近の変更による検索をこの順序にするにはどうすればよいですか (検索の「後」にソートするのではなく、最後に変更されたものに基づいて結果を見つけることに注意してください。)


github.com/shadkam/recentmostを希望されているものだろう-が、1つは、それを構築する必要がある
user3392225

回答:


153

これを使って:

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

printfからの引数man find

  • %Tk:で指定された形式のファイルの最終変更時刻k

  • @:1970年1月1日00:00 GMTからの秒数、小数部分。

  • c:ロケールの日付と時刻(1989年11月4日土12:02:33 EST 1989)。

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


5
1非常に便利です、私はリード/便利な日付の出力を発見したこれまで最初の答え
ジェイクN

最も信頼性の高い(そして非常に単純な)時間は数値的に連続しているため(したがって常に適切にソート可能)、thx!
アクエリアスパワー14年

1
私は私の最近のファイルを見つけるためにこのエイリアスを持っています~/.zshrcfr () { find ./ -iname "*"$@"*" -printf "%T@ %Td-%Tb-%TY %Tk:%TM %p\n" | sort -n | cut -d " " -f 2- | grep -i "$@" ; }それは再帰的にコマンドに渡された最初の引数のパターンを含むすべてのファイルを見つけ(fr <pattern>)、最新のもので最後にソートします。
joelostblom

これは素晴らしい !!!シンボリックリンクで使用するには、次を使用しますfind -L ...
Varun Chandak

1
あなたは使用することをお勧めしますssed秒の小数部分を取り除くためにとSTIL @PeterMortensenがあったとしてISO8601を使用しますfind . -type f -printf "%TY-%Tm-%TdT%TT %p\n" | sort -r | ssed -R 's/^([^.]+)\.\d+ (.*)$/\1 \2/'
ルドビクKuty

83

最も簡単な方法は、その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ユーティリティはない場合は、ヌルではなく改行を区切り文字として使用します。改行を含むファイル名のサポートが失われます。

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個を簡単に変更できます)。


このfindバージョンでは最も古いファイルが表示されるため、に-rオプションを追加する必要があると思いますsort
クエンティンプラデ

私のsedは-zオプションがないと言っています。
ケフシェクター

@KefSchecter次に、区切り文字として改行を使用しますが、ファイル名の改行のサポートは失われます。
ジル

上記はpython2用です。python3のみがある場合、いくつかの小さな変更:python3 -c 'import os、sys; sys.stdin.readlines()のfの場合、times = {}:f = f [0:-1]; times [f] = os.stat(f).st_mtime for f in(sorted(times.keys()、key = lambda f:times [f]、reverse = True))[:10]:print(f); '
ニールマクギル

40

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]*; ...


1
多数のファイルがある場合、lsの「引数リストが長すぎます」で失敗します。
オクルス

1
それは本当だが、私は質問が「どのように私は...簡単な見つけるのですか」であったと考えている
ЯрославРахматуллин

2
lsはxargsが理解できる方法でファイル名を引用しません(-0オプションはなく、さまざまな引用スタイルは不適切です)
東武14年

10

lsだけが必要です

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

または

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

2
多数のファイルがある場合、lsの「引数リストが長すぎます」で失敗します。xargsを使用することをお勧めしますか?
オクルス

2
しかし、複数回xargs呼び出すlsと、ソートが壊れます。
アーロンD.マラスコ

名前にスペースが含まれるファイルの場合、これは失敗します。何かアドバイス?
user74094

この答えにつまずいたのは、まさに同じような状況で私が必要としていたものでした。質問:+;最後に何をしますか?なしでは同じ結果が得られるようですが;+?なしでは機能しません。
RocketNuts

これは、別の答えは使用についての一部を除いて、8ヶ月前に掲載さ「を見つける`-1rt LSを...`」、壊れているだけで同じである
クレマン

7

user195696の答えを拡張する:

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

各ファイルに対して、これは最初に数値のタイムスタンプ(並べ替え、続いて集計\t)を出力し、次に人間が読めるタイムスタンプ、次にファイルサイズ(残念ながらfind's -printfはメビバイトではできません、キビバイトのみ)、次に相対ファイル名を出力します道。

次にsort -n、最初の数値フィールドでソートします。

次にcut、ユーザーにとって関心のない最初の数値フィールドを取り除きます。(2番目以降のフィールドを印刷します。)デフォルトのフィールド区切り文字は、\tまたは集計です。

出力の例:

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

filesizeフィールドを意図的に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 時間で並べ替えますが、これはここでは無関係ですが、私は通常それを使用します。


1
注:代わりにファイルサイズでソートするには、上記のいずれかのコマンドでT@by sを置き換えるだけです。
エフゲニーセルゲイエフ14

3

@ 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) }'
    

2

これにより、Mac OS Xでジョブが完了することがわかりました(他のUnixenでも動作するのに十分な汎用性があります)。

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

2
残念なことに、これは私のクロアチアの設定でローカライズされた月の名前を出力し、ソートを不正確にします。
イヴァンヴチカ

user195696の答えは、クロアチアのセットアップ(およびその他)で機能します。
ピーターモーテンセン

1

あなたの場合はfind選択が非常に簡単です、あなたはそれなしで行うことができる、とだけ使用することがありますls

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

1

試してください:

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

ただし、-mmin/ -mtimeとでデータをフィルタリングすることも便利です-type


1

つかいます:

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

私は、ファイル名に空白文字を処理するために、このsriptを改善し、参照superuser.com/a/777007/134532
1月


0

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


0

ファイル名の空白を正しく処理するスクリプトを作成することで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

すべてのPNGファイルを時間順に並べる場合$PWD

このシンプルなワンライナーは、regexp on findおよびonの柔軟性をすべて提供しlsます。

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

0

この方法でstat、BSDおよびLinux(POSIXではなく)で使用できます。

$ 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

sort | head日付によるクリーンで堅牢な方法があります:

ls -lプリティプリントに使用する

find . ! -type d -printf "%T@ %p\0" |
    sort -zrn |
    head -zn 10 |
    sed -z 's/^[0-9.]\+ //' |
    xargs -0 ls -lt

関数として:

findByDate() {
    local humansize=''
    [ "$1" = "-h" ] && humansize='h' && shift
    find . ${2:-! -type d} -printf "%T@ %p\0" |
        sort -zrn |
        head -zn ${1:--0} |
        sed -z 's/^[0-9.]\+ //' |
        xargs -0 ls -dlt${humansize}
}

これは、1つまたは2つの引数を指定して実行することも、次の引数を指定せずに実行することもできます。

Usage: findByDate [-h] [lines] [find options]

サンプル:

findByDate

日付でソートされたすべての非ディレクトリをリストします。注意:

大きなファイルシステムツリーでも、xargs すでにソートされたリストを受信するため、ls何度も実行する必要がある場合でも、ファイルの順序は正しいままです。

findByDate -h 12

日付順にソートされた12個の最近のディレクトリをリストします。サイズは人間が読める形式で印刷されます

findByDate 42 '-type l'

42個の最近のシンボリックリンクをリストします

findByDate -0 '( -type l -o -type b -o -type s -o -type c )'

日付順にソートされたすべてのシンボリックリンク、ブロックデバイス、ソケットおよびキャラクターデバイスをリストします。

反転順序

交換headによるtailとのスイッチを変更するsortls

findByDate() {
    local humansize=''
    [ "$1" = "-h" ] && humansize='h' && shift
    find . ${2:-! -type d} -printf "%T@ %p\0" |
        sort -zn |
        tail -zn ${1:-+0} |
        sed -z 's/^[0-9.]\+ //' |
        xargs -0 ls -dltr${humansize}
}

同じ機能、同じ使用法:

Usage: findByDate [-h] [lines] [find options]

-1

各アイテムの完全なパスを取得するだけの場合は、次のように書き留めます。

 find FIND_ROOT -maxdepth 1 -type f -printf "%T@ %p\n" | sort -nr | head -10 | cut -d ' ' -f 2

ここで、
-printf "%T @%p \ n"はソート基準(日付)を指定し、
'sort -nr'は日付によるソートを、
head -10は上位10件の結果を一覧表示、
cut -d '' -f 2は各行の先頭のタイムスタンプ。


cut -d ' ' -f 2ファイル名にスペースが含まれていると壊れます。
F.ハウリ

-3

簡単な解決策があります。

cdディレクトリに移動した後、

find . -iname "*" -ls


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