如何recursion查找目录中的最新修改的文​​件?

看起来ls在进行recursion调用时不能正确sorting文件:

 ls -altR . | head -n 3 

如何find目录中最近修改的文件(包括子目录)?

 find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " 

对于一棵巨大的树,可能很难将所有东西都留在记忆中。

%T@给你的修改时间就像一个unix时间戳, sort -n数字sort -ntail -1取最后一行(最高时间戳), cut -f2 -d" "从输出中cut -f2 -d" "第一个字段(时间戳) 。

编辑:就像-printf可能是GNU-only一样,ajreals stat -c用法也是如此。 虽然在BSD上可以这样做,但是格式化的选项是不同的(看起来-f "%m %N" ),

而我错过了复数的一部分; 如果你想要更多最新的文件,只是碰上尾部参数。

跟随@ plundra的答案 ,这里是BSD和OS X版本:

 find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -rn | head -1 | cut -f2- -d" " 

而不是sorting结果,只保留最后修改的结果,你可以使用awk打印修改时间最长的文件(在unix时间内):

 find . -type f -printf "%T@\0%p\0" | awk ' { if ($0>max) { max=$0; getline mostrecent } else getline } END{print mostrecent}' RS='\0' 

如果文件数量足够大,这应该是解决您的问题的更快的方法。

我使用了NUL字符(即'\ 0'),理论上,一个文件名可以包含任何字符(包括空格和换行符)。

如果你的系统中没有这样的病态文件名,你也可以使用换行符:

 find . -type f -printf "%T@\n%p\n" | awk ' { if ($0>max) { max=$0; getline mostrecent } else getline } END{print mostrecent}' RS='\n' 

此外,这也在mawk中工作。

这似乎工作正常,即使有子目录:

 find . -type f | xargs ls -ltr | tail -n 1 

如果文件太多,请优化查找。

我很难findSolaris 10下的最后一个修改过的文件。在这里find printf选项, stat不可用。 我发现了以下解决scheme对我来说很好:

 find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7 }' | sort | tail -1 

显示文件名以及使用

 find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1 

说明

  • find . -type f find . -type f查找并列出所有文件
  • sed 's/.*/"&"/'将path名用引号括起来以处理空格
  • xargs ls -E将引用的path发送给ls-E选项确保返回完整的时间戳记(格式年 – 月 – 日 – 小时 – 分 – 秒 – 纳秒
  • awk '{ print $6," ",$7 }'只提取date和时间
  • awk '{ print $6," ",$7," ",$9 }'提取date,时间和文件名
  • sort返回按datesort的文件
  • tail -1只返回最后一个修改过的文件

这给出了一个sorting列表:

 find . -type f -ls 2>/dev/null | sort -M -k8,10 | head -n5 

通过在sorting命令中放置'-r'来颠倒顺序。 如果你只想要文件名,插入“awk”{print $ 11}“|” 之前| | 头'

显示具有人类可读时间戳的最新文件:

 find . -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1 

结果如下所示:

 2015-10-06 11:30: +0200 ./foo/bar.txt 

要显示更多文件,请用更高的数字replace-n1

这个简单的cli也可以工作:

 ls -1t | head -1 

您可以将-1更改为要列出的文件数

这将recursion地将当前目录中所有目录的修改时间更改为每个目录中最新的文件:

 for dir in */; do find $dir -type f -printf '%T@ "%p"\n' | sort -n | tail -1 | cut -f2- -d" " | xargs -I {} touch -r {} $dir; done 

在Ubuntu 13上,下面是它,也许有点快,因为它颠倒了sorting,并使用“头”而不是“尾巴”,减less了工作。 在树中显示11个最新的文件:

找 。 -type f -printf'%T @%p \ n'| sort -n -r | 头-11 | cut -f2- -d“”| sed -e's,^。/ ,,'| xargs ls -U -l

这给出了一个完整的ls列表,而不需要重新sorting,省略了烦人的'./',这个'find'放在每个文件名上。

或者,作为一个bash函数:

 treecent () { local numl if [[ 0 -eq $# ]] ; then numl=11 # Or whatever default you want. else numl=$1 fi find . -type f -printf '%T@ %p\n' | sort -n -r | head -${numl} | cut -f2- -d" " | sed -e 's,^\./,,' | xargs ls -U -l } 

但是,大部分工作都是由plundra的原始解决scheme完成的。 感谢plundra。

我面临同样的问题。 我需要recursion地find最近的文件。 找了大概50分钟find。

这里有一个脚本可以更快地完成它:

 #!/bin/sh CURRENT_DIR='.' zob () { FILE=$(ls -Art1 ${CURRENT_DIR} | tail -n 1) if [ ! -f ${FILE} ]; then CURRENT_DIR="${CURRENT_DIR}/${FILE}" zob fi echo $FILE exit } zob 

这是一个获取目录的最新修改项的recursion函数。 如果这个项目是一个目录,那么recursion地调用这个函数并且search这个目录,等等。

如果在每个文件上分别运行stat是慢的,可以使用xargs来加快速度:

 find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -n | tail -1 | cut -f2- -d" " 

我发现上面的命令是有用的,但对于我的情况,我需要看到文件的date和时间,以及我的名字中有空格的几个文件的问题。 这是我的工作解决scheme。

 find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " | sed 's/.*/"&"/' | xargs ls -l 

我一直使用类似的东西,以及最近修改过的文件的top-k列表。 对于大型的目录树, 避免sorting可以快得多 。 在刚刚排名前1的最新修改文件的情况下:

 find . -type f -printf '%T@ %p\n' | perl -ne '@a=split(/\s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()' 

在一个包含170万个文件的目录中,我在3.4s中获得了最新的一个,比使用sort的25.5s解决scheme提高了7.5倍。

我更喜欢这个,它更短:

 find . -type f -print0|xargs -0 ls -drt|tail -n 1 

以下命令在Solaris上工作:

 find . -name "*zip" -type f | xargs ls -ltr | tail -1 

我为这个问题写了一个pypi / github包,因为我也需要一个解决scheme。

https://github.com/bucknerns/logtail

安装:

 pip install logtail 

用法:尾巴改变文件

 logtail <log dir> [<glob match: default=*.log>] 

用法2:在编辑器中打开最新更改的文件

 editlatest <log dir> [<glob match: default=*.log>] 

忽略隐藏的文件 – 带有快捷的时间戳

处理文件名中的空格 – 不是你应该使用这些!

 $ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10 2017.01.25 18h23 Wed ./indenting/Shifting blocks visually.mht 2016.12.11 12h33 Sun ./tabs/Converting tabs to spaces.mht 2016.12.02 01h46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht 2016.11.09 17h05 Wed ./Word count - Vim Tips Wiki.mht 

更多find嘉豪可以通过下面的链接find。

我发现以下更短,更可解释的输出:

 find . -type f -printf '%TF %TT %p\n' | sort | tail -1 

鉴于标准化的ISO格式date时间的固定长度,字典sorting是好的,我们不需要-n选项。

如果您想再次删除时间戳,则可以使用:

 find . -type f -printf '%TFT%TT %p\n' | sort | tail -1 | cut -f2- -d' '