2011-06-07 18:23:57 +0000 2011-06-07 18:23:57 +0000
152
152
Advertisement

Unix/Linux の検索とソートを更新した日付で行う

Advertisement

最近変更された順に結果を表示するような単純なfindはどうすればいいのでしょうか?

これが私が使用している現在のfindです(PHPでシェルエスケープをしているので、変数の理由はこれです)。

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

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

Advertisement
Advertisement

回答 (17)

168
168
168
2013-02-05 13:31:01 +0000

これを使います。

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

printf man find からの引数。

  • %Tk. kで指定されたフォーマットでのファイルの最終更新時刻。

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

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

  • %p. ファイル名。

85
85
85
2011-06-07 18:39:34 +0000

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

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

GNU findがあれば、ファイルの変更時間を表示させて、それでソートします。

find -type f -printf '%T@ %p```
find -type f -printf '%T@ %p\n' |
sort -k 1nr |
sed 's/^[^]* //' | head -n 10
```' |
sort -zk 1nr |
sed -z 's/^[^]* //' | tr '```
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];
    }'
```' '\n' | head -n 10

GNU findを持っていて、他のGNUユーティリティを持っていない場合は、ヌルの代わりに改行をセパレータとして使用してください。

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'

Perlの場合(ここではファイル名に改行がないと仮定します):

0x1&

Pythonの場合(同じくファイル名に改行がないと仮定します):

0x1&

PHPでも同じようにする方法があると思いますが、私は知りません。

POSIXツールだけで作業したい場合は、もっと複雑になります; 更新日でソートされたファイルを再帰的にリストアップする方法 (statコマンドは利用できません!) (最初の10個を再調整するのは簡単な部分です) を参照してください。

41
Advertisement
41
41
2011-06-16 18:11:00 +0000
Advertisement

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

10
10
10
2012-05-18 07:58:06 +0000

必要なのは ls

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

または

ls -1rt `find /wherever/your/file/hides -type f`
``` のようにすることができます。
8
Advertisement
8
8
2014-04-24 08:12:01 +0000
Advertisement

拡張 user195696さんの回答 .

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

各ファイルについて、これは最初に数値のタイムスタンプを出力し(ソートするためのもので、その後に集計\tが続く)、次に人間が読めるタイムスタンプを出力し、次にファイルサイズ(残念ながらfind-printfはmebibibytesではできず、kibibibytesのみ)を出力し、次に相対パスを含むファイル名を出力しています。

それから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

ファイルサイズフィールドをわざと6文字にしたのは、これ以上長くするとファイルの大きさが視覚的に判別しづらくなるからです。こうすることで、1e6 KiB以上のファイルが目立つようになります。1文字で1~9GB、2文字で10~99GBなどの意味です。

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

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 は時間順にソートする。

4
4
4
2016-02-24 15:18:34 +0000

user195696 さんの回答の OS X 版。

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

  1. タイムスタンプなし。
2
Advertisement
2
2
2019-03-12 19:32:27 +0000
Advertisement

FreeBSD (OS X) と Linux の両方で動作するシンプルなソリューションがあります。

2
2
2
2012-07-26 07:42:44 +0000

私はこれがMac OS X(そして他のUnixenでも動作するように十分に汎用的であることを発見しました)で仕事ができることを発見しました:

find . -type f -ls | awk '{print $(NF-3), $(NF-2), $(NF-1), $NF}' | sort
1
Advertisement
1
1
2013-12-08 09:14:14 +0000
Advertisement

使用例:

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
1
1
2014-05-02 11:16:59 +0000

findの選択が非常に簡単な場合は、lsを使わずに0x6&だけを使ってもいいかもしれません。

ls -1 *.cc # -r -t optional
0
0
0
2014-07-04 14:58:50 +0000

ファイル名の空白を正しく扱うようにして、Akashの回答を改善しました。

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
0
0
2019-09-11 08:23:43 +0000
find . ! -type d -printf "%T@ %p```
findByDate() {
    local humansize=''
    ["$1" = "-h"] && humansize='h' && shift
    find . ${2:-! -type d} -printf "%T@ %p```
Usage: findByDate [-h] [lines] [find options]
```" |
        sort -zrn |
        head -zn ${1:--0} |
        sed -z 's/^[0-9.] //' |
        xargs -0 ls -dlt${humansize}
}
```" |
    sort -zrn |
    head -zn 10 |
    sed -z 's/^[0-9.] //' |
    xargs -0 ls -lt

bash関数として。

findByDate

これは1つまたは2つの引数を指定して実行することもできますし、引数なしでも実行できます:

findByDate -h 12

サンプル:

findByDate 42 '-type l'

日付順にソートされた全ての非ディレクトリをリストアップします。注意:

大きなファイルシステムツリーでも、sort | head は既にソートされたリストを受け取るので、ls -l を何度も実行しなければならない場合でも、ファイルの順序は正しいままです。

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

さらに12の最新のディレクトリ以外のディレクトリを日付順にリストアップし、_人が読める形式でサイズを表示

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

さらに42の最新のシンボリックリンクをリストアップ

0x1&

すべてのシンボリックリンク、ブロックデバイス、ソケット、文字デバイスを日付順にリストアップします。

順番を反転

xargsls に置き換え、headtail のスイッチを変更。

0x1&

同一機能、同一用途。

0x1& 0x1&

0
0
0
2011-06-07 18:33:10 +0000

findには出力順序を変更するオプションはないと思います。-mtime-mmin は、結果を特定の時間枠内で変更されたファイルに制限することができますが、出力はソートされません – これはあなた自身で行う必要があります。GNU find には -printf オプションがあり、特に、見つかった各ファイルの修正時間を表示することができます (%t または %Tk の形式の文字列) ; これは、find の出力を好きなようにソートするのに役立つかもしれません。

0
0
0
2018-06-24 23:33:20 +0000

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
0
0
2014-05-17 10:55:57 +0000

全てのPNGファイルを$PWDで時間順に並べたい場合。

このシンプルなワンライナーは、findでの正規表現の柔軟性をすべて与えてくれます。

find $PWD -name "*.png" -print0 | xargs -0 ls -laht | less
-1
-1
-1
2017-03-28 01:13:40 +0000

各項目のフルパスを取得したい場合は、以下のように書きます。

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は各行の先頭のタイムスタンプをカットします。

-3
-3
-3
2017-03-25 09:09:59 +0000

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

cdでディレクトリにfind . -iname "*" -lsした後に

Advertisement

関連する質問

6
10
5
37
4
Advertisement
Advertisement