我在定义的目录中有一些 .xls 文件(例如 /A/B)。我想重命名前 10 个最新文件并在其名称中附加“-bkp”。
我试过了,没用
ls -lt *.xls | head -1 | awk '{print "mv " $9 " "$9-bkp}' | sh
我尝试了 find 和 -exec 但我们如何获取 top l0 最新修改的文件
答案1
您应该使用-10
and 不-1
作为 的参数head
,并且您还需要引号-bkp
,所以
ls -lt *.xls | head -10 | awk '{print "mv " $9 " "$9"-bkp"}' | sh
应该管用。如果您尝试删除| sh
,您可能会意识到,因此命令只是以 awk 打印命令结束。
答案2
如果您不想对文件名可能包含的字符进行任何假设,您可以这样做:
ls -dt ./*.xls | awk -v q="'" -v n=10 '
function process() {
if (NR > 1) {
gsub(q, q "\\" q q, file)
print "mv " q file q, q file "-bkp" q
if (!--n) exit
}
}
/\// {
process()
file = $0
next
}
{file = file "\n" $0}
END {process()}' | sh -x
或者如果您有zsh
:
for f (*.xls(om[1,10])) cp -- $f $f-bkp
或者
autoload zmv
zmv -C '*.xls(#qom[1,10])' '$f-bkp'
答案3
如果您有 ksh93 (用于数组) 和 perl (用于时间戳/统计),那么这将有效:
files=(*.xls)
# exit early if there are no matching files
[ "$files" = "*.xls" ] && exit 0
for index in ${!files[@]}
do
t[$index]=$(perl -e '$x=(stat(shift))[9]; print "$x"' "${files[index]}")
done
for i in ${!t[@]}
do
printf "%d %d\n" ${t[i]} $i
done | sort -rn | head -10 | while read t i
do
mv "${files[i]}" "${files[i]}-bkp"
done
它的工作原理是收集 *.xls 文件列表,然后循环这些文件,调用perl
单行函数打印每个文件的最后修改时间戳,将结果保存到并行数组中t
。
然后循环遍历 t,打印时间戳和数组索引,通过管道将其传送sort
到开头以获取最近修改的文件,通过管道将其传送至head
前 10 个文件,然后循环返回该输出以mv
调用相应的文件。
答案4
ls 有一个“sort”参数,可以采用“time”值。
#!/bin/bash
IFS=$'\n'
for file in $(ls *.xls --sort=time|head -n 10);
do
mv $file $file-bkp
done
unset IFS
IFS 恶作剧是因为如果文件名中有空格,for 循环就会变得不礼貌。我相信这个问题有更正统的解决方案,但我的解决方案有效。如果您知道文件名不包含空格,则可以删除包含 IFS 的行。