我编写了代码来更改大量文件的名称,它应该用下划线替换空格,并将所有文件名小写。
这是代码
for file in *;
do mv "$file" `echo $file | sed -e 's/ */_/g' -e 's/_-_/-/g'`;
do mv -f "$file" `echo "$file" | tr A-Z a-z`;
done;
我知道变量$file
将在第二行之后发生变化,因此它会在第三行出现错误
我可以把它分成两个循环,然后它就可以工作了,但我需要建议如何for
只在一个循环中解决这个问题
答案1
要重命名文件,使用 perlrename
实用程序(有时称为prename
)可能更简单。不过,我假设您这样做是为了练习学习 shell 脚本。
为了解决眼前的问题,您所需要的只是第二个 shell 变量,这里称为new
:
for file in *
do
new=$(echo "$file" | sed -e 's/ */_/g' -e 's/_-_/-/g')
mv -f "$file" "$(echo "$new" | tr A-Z a-z)"
done
另一种方法是扩展管道:
for file in *
do
mv -f "$file" "$(echo "$file" | sed -e 's/ */_/g' -e 's/_-_/-/g' | tr A-Z a-z)"
done
如果您有 GNU sed,那么管道可以进一步简化:
for file in *
do
mv -f "$file" "$(echo "$file" | sed -e 's/ */_/g' -e 's/_-_/-/g' -e 's/.*/\L&/')"
done
笔记
由于您使用了
-f
选项mv
,因此该脚本可能会导致目录中的文件被覆盖并导致其内容丢失。考虑使用
$(...)
代替反引号进行命令替换。美元括号形式嵌套良好,视觉上清晰,并避免了由于许多字体没有显示反引号和常规引号之间的明显差异而发生的混淆。许多语言要求每个命令末尾都有一个分号。shell 不是这样的语言:换行符就像分号一样结束命令。