这个灵魂会这样做:
for f in *.pdf
do
mv "$f" "${f//[^0-9]/}.pdf"
done
但你最好先尝试一下:
for f in *.pdf
do
echo mv "$f" "${f//[^0-9]/}.pdf"
done
请注意,abc4.pdf 和 zzz4.pdf 都将重命名为 4.pdf。所以也许你使用mv -i
而不仅仅是mv。
更新: 解释:
我想第一部分已经很清楚了;*.pdf
称为 globbing,匹配所有以 .pdf 结尾的文件。for f in ...
只是迭代它们,每次将 f 设置为其中之一。
for f in *.pdf
do
mv "$f" "${f//[^0-9]/}.pdf"
done
I guess
mv source target
也很清楚。如果文件名为“Unnamed File1”,则需要用引号将其屏蔽,否则 mv 会读取
mv Unnamed File1 1.pdf
这意味着,它有多个文件要移动,Unnamed 和 File1,并且会将 1.pdf 解释为将这两个文件移动到的目录。
好吧,我想真正的问题在这里:
"${f//[^0-9]/}.pdf"
有字符的外部粘合。就这样吧
foo=bar
一些变量赋值然后
$foo
${foo}
"$foo"
"${foo}"
有四种合法的引用方式。最后两个用于掩盖空白等,所以这在某些情况下没有区别,在某些情况下有区别。
如果我们把东西粘在一起
$foo4
${foo}4
"$foo"4
"${foo}"4
第一种形式不起作用 - shell 将查找变量 foo4。所有其他 3 个表达式都引用 bar4 - 首先 $foo 被解释为 bar,然后附加 4。对于某些字符不需要屏蔽:
$foo/fool
${foo}/fool
"$foo"/fool
"${foo}"/fool
都会以同样的方式解释。所以无论“${f//[^0-9]/}”是什么,“${f//[^0-9]/}.pdf”都是附加在它后面的“.pdf”。
我们接近所有谜团的核心:
${f//[^0-9]/}
这是以下形式的替换表达式
${variable//pattern/replacement}
- 变量是$f(这里我们可以省略大括号内的$),上面说的是$f。那很简单!
- 替换是空的——那就更容易了。
- 但是 [^0-9] 确实很复杂,不是吗?
-
[0-9]
只是从 0 到 9 的所有数字的组,其他组可以是:
[0-4] digits below 5
[02468] even digits
[a-z] lower case letters
[a-zA-Z] all (common latin) characters
[;:,/] semicolon, colon, comma, slash
前面的插入符号 ^ 作为第一个字符是该组的否定:
[^0-9]
表示除 0 到 9(包括点、逗号、冒号...)之外的所有内容都在组中。一起:
${f//[^0-9]/}
从 $f 中删除所有非数字,并且
"${f//[^0-9]/}.pdf"
附加 .pdf - 整个内容被屏蔽。
${v//p/r}
及其朋友(有很多有用的)在中进行了解释man bash
在本章中Parameter Expansion
。对于该小组,我手头没有进一步阅读的资源。