如何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 -n
, tail -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' '