我想根据以下规则将目录中的文件重命名为连续的数字:
文件名-[某个日期]=>文件名-[前一天日期]
例如,file20170329
file20170328
和file20170327
将重命名为file20170328
file20170327
和file20170326
。
我有大约 100 个文件,因此我需要一个比单独重命名每个文件更好的技巧。
答案1
如果您有 100 个文件(并且有权访问 perl rename
,Ubuntu 中通常是这种情况),您可以使用:
for n in {100..1}; do rename -n "s/$(date --date="$n days ago" +"%Y%m%d")/$(date --date="$(($n+1)) days ago" +"%Y%m%d")/" *; done
现在,当您使用它-n
进行测试时,它会出现如下抱怨:
rename(file20170217, file20170216)
file20170218 not renamed: file20170217 already exists
file20170219 not renamed: file20170218 already exists
但是当您运行它时,-n
该文件不再存在,因此重命名成功:
for n in {100..1}; do rename "s/$(date --date="$n days ago" +"%Y%m%d")/$(date --date="$(($n+1)) days ago" +"%Y%m%d")/" *; done
如果您有超过 100 个文件,则需要增加范围{150..1}
或其他。
这很慢。重命名 100 个文件可能需要 2 分钟或更长时间。但它有效。
答案2
以下脚本:
- 对于每个文件
- 如果文件名大于 8(即能够保存日期)
- basefilename 保存不包含最后 8 个字符的文件名
- 今日-保存最后 8 个字符(日期)
- 昨天 - 保存 $TODAY 前一天的 8 个字符
mv
我创建了一个/tmp/storage
文件夹,脚本会将文件复制到该位置。这样,如果两个文件的基本文件名相同,但日期相差一天,重命名一个文件不会损坏另一个文件
注意:为了允许脚本执行,应该从行中cp
删除echo
echo cp ...
mkdir -p /tmp/storage
for f in *
do
if [ "${#f}" -gt 8 ]; then
filebasename=${f::-8}
TODAY=${f: -8}
YESTERDAY=`date '+%C%y%m%d' -d "$TODAY-1 days"`
echo cp $f /tmp/storage/${f//$TODAY}$YESTERDAY;
fi
done
例子:
$ ls *20*
aaa2hhh20170329 aaahhh20170329 xajds20170222 xajsxs20170224
脚本结果:
cp aaa2hhh20170329 /tmp/storage/aaa2hhh20170328
cp aaahhh20170329 /tmp/storage/aaahhh20170328
cp xajds20170222 /tmp/storage/xajds20170221
cp xajsxs20170224 /tmp/storage/xajsxs20170223