題 Unix / Linux按日期修改查找和排序


我怎麼能做一個簡單的事情 find 哪個會按最近修改的順序排序?

這是當前的 find 我正在使用(我在PHP中進行shell轉義,因此這是變量的推理):

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

我怎麼能通過最近修改過的搜索順序? (注意我不希望它在搜索之後排序,而是根據最近修改的內容查找結果。)


108
2018-06-07 18:23


起源


github.com/shadkam/recentmost 會做什麼 - 但人們需要建立它 - user3392225


答案:


用這個:

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

printf 來自的論點 man find

  • %Tk:文件的最後修改時間,格式為 k

  • @:1970年1月1日格林尼治標準時間00:00以來的秒數,小數部分。

  • c:locale的日期和時間(Sat Nov 04 12:02:33 1989 1989)。

  • %p:文件名。


109
2018-02-05 13:31



+1非常有用,我發現第一個答案是可讀/有用的日期輸出 - Jake N
最可靠(也很簡單)因為時間被賦予數字順序(因此總是可以正確排序),thx! - Aquarius Power
我有這個別名來查找我的近期文件 ~/.zshrc: fr () { find ./ -iname "*"$@"*" -printf "%T@ %Td-%Tb-%TY %Tk:%TM %p\n" | sort -n | cut -d " " -f 2- | grep -i "$@" ; } 它以遞歸方式查找包含傳遞給命令的第一個參數模式的所有文件(fr <pattern>)並用最新的最後一個對它們進行排序。 - joelostblom
對於 ISO 8601 日期輸出,使用 find . -printf "%T@ %CY-%Cm-%CdT%CH:%CM:%CS %p\n" | sort -n。由於它自然排序,它也可以直接在排序中使用: find . -printf "%CY-%Cm-%CdT%CH:%CM:%CS %p\n" | sort -n - Peter Mortensen


最簡單的方法是使用zsh,這要歸功於它 全球限定詞

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

如果您有GNU查找,請使其打印文件修改時間並按此排序。

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

如果您有GNU查找而不是其他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個是容易的部分)。


80
2018-06-07 18:39



我覺得 find 版本顯示最舊的文件,並且您需要添加 -r 選項 sort。 - Quentin Pradet
我的sed說它沒有-z選項。 - Kef Schecter
@KefSchecter然後使用換行符作為分隔符,但是你將失去對文件名中換行符的支持。 - Gilles
以上是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); “ - Neil McGill


你不需要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]*; ... 


32
2018-06-16 18:11



如果有很多文件,則會失敗,並且ls上的“參數列表太長”。 - occulus
這是真的,但我相信問題是“我怎麼做一個簡單的發現......” - Ярослав Рахматуллин
ls不會以xargs可以理解的方式引用文件名(沒有-0選項,並且各種引用樣式不合適) - Tobu


你只需要 LS

你可以做到 find /wherever/your/files/hide -type f -exec ls -1rt "{}" +; 如上所述,

要么

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

10
2018-05-18 07:58



如果有很多文件,則會失敗,並且ls上的“參數列表太長”。也許重新使用xargs? - occulus
但如果 xargs 電話 ls 多次,排序將被打破。 - Aaron D. Marasco
對於名稱中包含空格的文件,此操作失敗。任何建議? - user74094


擴展 user195696的回答

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

對於每個文件,首先輸出數字時間戳(用於排序,然後是製表) \t),然後是人類可讀的時間戳,然後是文件大小(不幸的是 find-printf 不能在mebibytes,只有kibibytes),然後文件名與相對路徑。

然後 sort -n 按第一個數字字段對其進行排序。

然後 cut 擺脫了用戶不感興趣的第一個數字字段。 (向前打印第二個字段。)默認字段分隔符為 \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 按時間排序,這與此無關,但這是我通常使用的。


3
2018-04-24 08:12



注意:按文件排序 尺寸 相反,只需更換 T@ 通過 s 在上述任一命令中。 - 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) }'
    

2
2018-02-24 15:18





我發現這可以在Mac OS X上完成工作(並且通用性足以在其他Unixen上工作):

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

1
2017-07-26 07:42



遺憾的是,這會在我的克羅地亞語設置上打印出本地化的月份名稱,使得排序不正確。 - Ivan Vučica
user195696的回答 適用於克羅地亞人(以及其他人)。 - Peter Mortensen


如果你的 find 選擇很簡單,你可能沒有它,只需使用 ls

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

1
2018-05-02 11:16





使用:

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
2017-12-08 09:14



我改進了這個sript以處理文件名中的空格,請參閱 superuser.com/a/777007/134532 - jan