我有这样的文件夹结构:
drwxr-xr-x 2 root root 4096 Jun 30 21:34 dir_0.0.1_2
drwxr-xr-x 2 root root 4096 Jul 2 23:45 dir_0.0.1_1
-rw-r--r-- 1 root root 24 Jul 3 00:03 a.sh
drwxr-xr-x 2 root root 4096 Jul 3 00:04 dir_0.0.1_3
脚本在同一目录上dir_0.0.1
创建一个名为 : 的新目录。a.sh
如何在脚本中应用计数器,以便将新形成的目录重命名为dir_0.0.1_4
?
答案1
在 zsh 中:
set -- dir_0.0.1_*(oe['REPLY=${REPLY##*_}']n[-1])
mv dir_0.0.1 dir_0.0.1_$(( ${1##*_} + 1 ))
这将位置参数(仅$1
在此处使用)设置为通配符的扩展dir_0.0.1_*(oe['REPLY=${REPLY##*_}']n[-1])
:
- 文件名必须以
dir_0.0.1_
- 然后
o
使用后续e[ ... ]
表达式对文件名进行排序(排序),其中 - 将排序键设置为文件名的一部分,该部分是通过剥离尽可能多的前导字符直到最后的
_
下划线而产生的 n
按数字排序- 然后对文件名列表进行切片以返回最后一个元素 (
[-1]
)
当前索引最大的文件名现在位于$1
.该数字在数字扩展内检索$(( ))
(同样,通过通过 剥离前导字符_
),然后添加 1 并在前面添加静态前缀。
在 bash 中,我会循环遍历文件名并手动比较索引:
# safe starting point
greatest=-1
for d in dir_0.0.1_*; do n=${d##*_}; [ "$n" -gt "$greatest" ] && greatest=$n; done
mv dir_0.0.1 dir_0.0.1_$(( greatest + 1))
bash 循环的细分(实际上与 sh 兼容):
- 我们首先为索引设置一个大概安全的起点——保证低于我们发现的任何起点
- 使用
for
带有通配符的循环来获取现有的目录名称;对于每个目录: - 通过删除从前面到最后一个下划线的所有内容来捕获末尾的索引
- 测试该索引以查看它是否大于当前最高索引;如果是,则重置最高索引
- 循环完成后,通过附加“最高+ 1”值重命名目录
另一种选择是对索引进行强力循环,直到找到未使用的索引:
# set this to something you know exists
index=1
while [ -e dir_0.0.1_"${index}" ]; do index=$((index + 1)); done
mv dir_0.0.1 dir_0.0.1_"${index}"
该值会递增$index
,直到对应名称的目录出现为止不是存在。然后我们使用该未使用的号码进行重命名。