我有以下文件
SSt12.precip.374.sub.climatology.ctl
SSt12.precip.2874.sub.climatology.ctl
SSt12.precip.3764.sub.climatology.ctl
SSt12.precip.6774.sub.climatology.ctl
我想将文件重命名为
SSt12.precip.1.sub.climatology.ctl
SSt12.precip.2.sub.climatology.ctl
SSt12.precip.3.sub.climatology.ctl
SSt12.precip.4.sub.climatology.ctl
答案1
和zsh
:
$ autoload zmv
$ n=0; zmv -n '(*.)<->(*.ctl)(#qn)' '$1$[++n]$2'
mv -- SSt12.precip.374.sub.climatology.ctl SSt12.precip.1.sub.climatology.ctl
mv -- SSt12.precip.2874.sub.climatology.ctl SSt12.precip.2.sub.climatology.ctl
mv -- SSt12.precip.3764.sub.climatology.ctl SSt12.precip.3.sub.climatology.ctl
mv -- SSt12.precip.6774.sub.climatology.ctl SSt12.precip.4.sub.climatology.ctl
(再次执行此操作,而不-n
实际执行重命名)。
使用 GNU 工具并假设文件名不包含换行符,您可以这样做:
ls -v | awk -F. -vOFS=. -vORS='\0' '/\.ctl$/{print;$3=++n;print}' |
xargs -r0n2 echo mv --
(删除echo
以实际进行重命名)
答案2
printf 'cp SSt12.precip.374.sub.climatology.ctl \
SSt12.precip.%d.sub.climatology.ctl\n' $(seq 5) |
. /dev/stdin
显然你的意思是改名- 很抱歉对于这个误会。
但如果确实如此...说 374 - 378 ...
printf 'n=%d ; mv SSt12.precip.$((373+n)).sub.climatology.ctl \
SSt12.precip.${n}.sub.climatology.ctl\n' $(seq 5) |
. /dev/stdin
关于您上面的评论 - 假设它们位于同一目录中并且它们是唯一匹配的文件SSt12.precip.*.sub.climatology.ctl
:
set -- SSt12.precip.*[67]4.sub.climatology.ctl
printf 'echo mv %s SSt12.precip.$((n=n+1)).sub.climatology.ctl\n' "$@" |
. /dev/stdin
我已经用echo
上面的方法削弱了它,这样你就不会因为我的帐户而感到遗憾。在目前的形式下,它只会显示它想要做什么。删除后echo
,文件就归您所有,可以移动或丢失。
请参阅下面 Stephane 的评论,了解有关正确排序顺序的说明 - 他是对的。
答案3
假设您实际上有多个文件而不是同一个文件,因此您想要重命名每个文件,您可以这样做:
for i in *ctl; do echo "$i"; done |
sort -t'.' -nk3 |
awk -F'.' -v OFS='.' '{printf "mv %s ", $0; $3=NR;print}' |
sh
上面假设您的文件名与您在问题中显示的完全相同。它们都有一个数字作为 3 点分隔的字段,并且都以 结尾ctl
。
答案4
第一个障碍是以正确的顺序获取文件。通配符模式SSt12.precip.*.sub.climatology.ctl
按字典顺序而不是数字顺序扩展文件名,因此它将文件按 2874、374、3764、6774 的顺序排列。
在 zsh 中,这很容易解决,这要归功于n
全局限定符( SSt12.precip.*.sub.climatology.ctl(n)
)。在其他 shell 中,这需要更多工作。您可以提取数字并对它们进行排序。只要文件名不包含任何换行符,这里就有一种方法。我通过剥离前两个点分隔的段,然后剥离除第一个点分隔的段之外的所有段来提取数字。
number=1
for x in SSt12.precip.*.sub.climatology.ctl; do
number="${x#*.*.}"; number="${number%%.*}"
printf "%d %s\n" "$number" "$x"
done | sort -k1,1n |
while IFS= read -r filename; do
filename=${filename#* }
suffix=${filename#*.*.*.}
prefix=${filename%.*."$suffix"}
mv -- "$filename" "$prefix.$number.$suffix"
number=$((number+1))
done