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

find linux sorting unix

最近変更された順に結果を並べるような単純なfindはどうすればいいですか?

現在私が使っているfindは以下の通りです(PHPでシェルエスケープをしているので、変数の理由はそれになります)

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

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

  177  None  2011-06-07


ベストアンサー

Use this:

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

man findからのprintfの引数

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

  • @: 1970年1月1日0時00分GMTからの秒数

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

  • %p:ファイルの名前

204  user195696  2013-02-05


最も簡単な方法は、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 個を再調整するのは簡単です)

88  Gilles ‘SO- stop being evil’  2011-06-07


あなたは、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]*; ...

44  Ярослав Рахматуллин  2011-06-16


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

Where:

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

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

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

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

11  Evgeni Sergeev  2014-04-24


必要なのはlsだけです

上記のようにfind /wherever/your/files/hide -type f -exec ls -1rt "{}" +;でも良いのではないでしょうか

or

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

10  skippy1910  2012-05-18


私は、FreeBSD (OS X) と Linux の両方で動作するシンプルなソリューションを持っています

find . -type f -exec ls -t {} +

5  Alex Shchur  2019-03-12


@user195696さんの回答のOS X変種

  1. With timestamp:

    find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r
    
  2. Without timestamp:

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

4  user9399  2016-02-24


これはMac OS Xでも仕事ができることがわかりました(他のUnixenでも十分に使える汎用性があります)

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

2  Bryan Petty  2012-07-26


日付別に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]

Sample:

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

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

Inverting order

headtailに置き換え、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]

2  F. Hauri  2019-09-11


findの選択が非常に単純なものであれば、それを使わずにlsだけで済むかもしれません

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

1  djc  2014-05-02


Try:

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

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

1  None  2011-06-07


Use:

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  2013-12-08


findには出力順序を変更するオプションはないと思います。-mtime-mminでは、結果を特定の時間枠内で変更されたファイルに制限することができますが、出力はソートされません。GNU findには-printfオプションがあり、他のものの中では、見つかった各ファイルの変更時刻を表示することができます(書式は文字列%t%Tk)

0  Jim Lewis  2011-06-07


ファイル名のホワイトスペースを正しく扱うスクリプトにすることで、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  jan  2014-07-04


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

このシンプルなワンライナーは、findlsでの正規表現のすべての柔軟性を提供します

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

0  john smith  2014-05-17


BSDやLinuxではstatをこのように使うことができます(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  drewk  2018-06-24


各アイテムのフルパスを取得したいだけならば、このように書き留めておくことができます

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

-1  David Jung  2017-03-28


簡単な解決策があります

cdをディレクトリにした後、使用します

find . -iname "*" -ls

-3  sing  2017-03-25


タイトルとURLをコピーしました