![如何通过组合三个变量来批量重命名文件并忽略文件扩展名?](https://linux22.com/image/206102/%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87%E7%BB%84%E5%90%88%E4%B8%89%E4%B8%AA%E5%8F%98%E9%87%8F%E6%9D%A5%E6%89%B9%E9%87%8F%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6%E5%B9%B6%E5%BF%BD%E7%95%A5%E6%96%87%E4%BB%B6%E6%89%A9%E5%B1%95%E5%90%8D%EF%BC%9F.png)
我正在尝试创建一个重命名一组文件的脚本。通常它们是 TIF,但有时可能会出现一些奇怪的情况,所以我想重命名文件并忽略文件扩展名。
文件名全部相同,中间添加纪元时间作为区分符。最终结果将与此类似:
Name1=CLMSFILE
Name2=Epoch
Name3=_A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES
CLMSFILE53253_A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES.TIF (or other extension)
这就是我目前拥有的
#Rename files and insert epoch time
name1=$CLMSFILE
name2=$(date +%s%3N)
name3=$_A\ BUNCH\ OF\ OTHERTEXT_WITH_A_MIXTURE\ OF\ UNDERSCORES\ AND_SPACES
for f in *; do
newname=$name1$name2$name3
mv -n "$f" "${newname}"
done
运行此命令后,我只重命名第一个文件,但它忽略第一个变量并且没有扩展名。
1653049404956 _A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES
220220217SOMEORG20003_01.TIF
220220217SOMEORG30004_01.TIF
答案1
您的 shell 脚本中有几个问题会导致您观察到的错误:
你说名字的一部分是 be
CLSMFILE
。但是,在您声明的变量赋值中name1=$CLMSFILE
,因此您将内容分配给第一部分一个名为的 shell 变量CLSMFILE
,它可能不存在,因此是空的。对于该部分来说实际上也是如此name3
,但是您碰巧以 , 开始字符串_
,并且$_
在 shell 中具有特殊含义,因此解释在 后立即停止,_
并且字符串的其余部分原封不动地导入到您的变量中。您的脚本将尝试将所有文件重命名为相同的名称。幸运的是,您使用了该
-n
选项,否则您将丢失目录中除最后一个文件之外的所有文件。原因是
date
命令 inname2=$(date ...)
只被评估在进行赋值时,而不是每次$name2
使用变量时。因此它对于循环的所有迭代都是恒定的。您声明想要有文件扩展名,但您忘记向文件添加扩展名。
mv
重命名整个文件名,不仅仅是 之前的部分,仅仅是因为文件名中允许有.
多个。.
我建议你使用shellcheck
,也可作为独立工具使用,用于捕获 shell 脚本中的错误。
以下修改应该有效:
name1="CLMSFILE"
name3="_A BUNCH OF OTHERTEXT_WITH_A_MIXTURE OF UNDERSCORES AND_SPACES"
for f in *; do
basename=${f%.*}
newbasename="$name1$(date +%s%3N)$name3"
newname=${f/$basename/$newbasename}
mv -n "$f" "${newname}"
done
这使用 shell 字符串操作来
- 将 的“basename”部分
$f
(即最后一个分隔部分之前的所有内容.
)存储在变量中$basename
- 根据您的规则生成新的基本名称,但
date
为每个循环迭代运行该命令 $basename
将 的子串替换$f
为$newbasename
- 相应地重命名文件
理想情况下,您可以mv -n ...
用类似的东西替换该部件
echo "Renaming '$f' to '$newname'"
直到您确定名称生成逻辑正常工作。