重命名 AIX 上最近修改的 10 个文件

重命名 AIX 上最近修改的 10 个文件

我在定义的目录中有一些 .xls 文件(例如 /A/B)。我想重命名前 10 个最新文件并在其名称中附加“-bkp”。

我试过了,没用

ls -lt *.xls | head -1 | awk '{print "mv " $9 " "$9-bkp}' | sh

我尝试了 find 和 -exec 但我们如何获取 top l0 最新修改的文​​件

答案1

您应该使用-10and 不-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 的行。

相关内容