在一个目录中,我有许多文件,我需要对最近修改的带有后缀的文件执行一些操作.txt
。
理想情况下,我想做
myutility "$newest"
最后,哪里$newest
是最近修改的文件的路径名。
如果这另外可以推广,这样我就可以.txt
在目录层次结构中获取带有后缀的最近修改的文件,那就太好了,如果我可以获取例如五个最近修改的文件,以便我可以使用,那就更好了
myutility "${newest[@]}"
.txt
对整个目录层次结构中最近修改的五个文件运行我的实用程序。
bash
使用or 的解决方案ksh93
是最好的。
答案1
尽管您用和 glob 限定符标记了问题bash
and , :ksh
zsh
print **/*.txt(.om[1,5])
打印前 5 个带扩展名的纯文件 ( .
) .txt
,按修改时间升序排序 ( om
)
前任。
print **/*.txt(.om[1,5])
dir/file1.txt file2.txt dir/file.txt File1.txt File2.txt
答案2
您可以使用 ls 按修改时间(或创建或访问)列出文件。
简单地说
ls -t *.txt | head -n5
获取最近 5 个 .txt 文件
您可以使用 $() 或 xargs 将其输入 myutility。
ls -t *.txt | head -n5 | xargs myutility
如果需要递归,可以使用find。
find -type f -iname "*.txt" | xargs ls -t | head -n5 | xargs myutility
(可能的问题:您必须至少有一个 .txt 文件才能正常工作。您可以修复它,但这是最干净的解决方案)。
编辑:OP 想知道如何处理带空格的文件名。这是一种解决方案:
find -type f -iname "*.txt" | xargs ls -t | head -n5 | tr '\n' '\0' | xargs -0 myutility
如果你想解决上面提到的可能的问题,你可以检查头前的文件,find ..... | egrep '.*' || exit
或者简单地在 ls 中包含一些无意义的文件名并忽略类似的警告xargs ls -t ''
。
答案3
它可能看起来很难看,但使用find
获取文件是最可靠的方法,可以避免名称中空格和其他特殊字符的问题。你得到一个修改时间+文件的列表,按最近排序,得到顶部n(此处5
),删除时间,只留下文件名,并将其传递给您的脚本:
find dir -iname '*.txt' -printf '%T@\t%p\0' | sort -znr | head -z -n 5 | grep -zPo '^\S+\s+\K[\S\s]*' | xargs -0r myutility
如果您使用的是旧版本coreutils
(< v8.25head
不支持-z
) 或grep
(< v2.25 有一个错误),您可以使用脚本:
#!/bin/bash
flimit=5
filenames=()
while (( flimit-- )) && IFS=$'\t' read -r -d $'\0' mtime filename; do
filenames=("${filenames[@]}" "$filename")
done < <(find -name '*.txt' -printf '%T@\t%p\0' | sort -znr)
if [[ ${#filenames[@]} -gt 0 ]]; then
myutility "${filenames[@]}"
else
>&2 echo no files found
fi