在Bash中,如何清除目录中文件名中的所有数字,同时保持文件扩展名不变
我在这样的目录中有文件:
I have files in a directory like this:
asdfs54345gsdf.pdf
gsdf6456wer.pdf
oirt4534724wefd.pdf
我想将所有文件重命名为数字+ .pdf,以便将上述文件重命名为:
I want to rename all the files to just the numbers + .pdf so the above files would be renamed to:
54345.pdf
6456.pdf
4534724.pdf
最好是本机Bash命令或脚本(OSX 10.6.8)
The best would be a native Bash command or script (OSX 10.6.8)
我得到的一些线索包括
sed 's/[^0-9]*//g' input.txt
sed 's/[^0-9]*//g' input.txt > output.txt
sed -i 's/[^0-9]*//g' input.txt
echo ${A//[0-9]/} rename 's/[0-9] //' *.pdf
这很有趣:
for f in *.pdf
do
mv "$f" "${f//[^0-9]/}.pdf"
done
但是您最好先尝试一下:
but you better try before:
for f in *.pdf
do
echo mv "$f" "${f//[^0-9]/}.pdf"
done
请注意,abc4.pdf和zzz4.pdf都将重命名为4.pdf.因此,也许您使用mv -i
而不只是mv.
Note, that abc4.pdf and zzz4.pdf will both be renamed to 4.pdf. So maybe you use mv -i
instead of just mv.
我猜拳头很清楚; *.pdf
称为通配符,它匹配所有以.pdf结尾的文件. for f in ...
只是遍历它们,每次将f设置为其中之一.
I guess the fist part is clear; *.pdf
is called globbing, and matches all files, ending with .pdf. for f in ...
just iterates over them, setting f to one of them each time.
for f in *.pdf
do
mv "$f" "${f//[^0-9]/}.pdf"
done
我猜
mv source target
也很清楚.如果文件名为未命名的文件1",则需要用引号将其屏蔽,否则mv会读取
is clear as well. If a file is named "Unnamed File1", you need to mask it with quotes, because else mv will read
mv Unnamed File1 1.pdf
这意味着它有多个文件要移动,分别是Unnamed和File1,并将1.pdf解释为将两个文件都移动到的目录.
which means, it has multiple files to move, Unnamed and File1, and will interpret 1.pdf to be a directory to move both files to.
好的,我想真正的问题在这里:
Okay, I guess the real issue is here:
"${f//[^0-9]/}.pdf"
字符之间有外粘.成为
foo=bar
然后是一些变量赋值
$foo
${foo}
"$foo"
"${foo}"
是引用它们的四种合法方法.最后两个用于遮盖空白等,因此在某些情况下没有区别,在某些情况下是一样.
are four legitimate ways to refer to them. The last two used to mask blanks and such, so this is in some cases no difference, in some cases it is.
如果我们将某些东西粘在一起
If we glue something together
$foo4
${foo}4
"$foo"4
"${foo}"4
第一种形式不起作用-外壳将查找变量foo4.所有其他3个表达式均引用bar4-首先将$ foo解释为bar,然后附加4.对于某些字符,不需要遮罩:
the first form will not work - the shell will look for a variable foo4. All other 3 expressions refer to bar4 - first $foo is interpreted as bar, and then 4 is appended. For some characters the masking is not needed:
$foo/fool
${foo}/fool
"$foo"/fool
"${foo}"/fool
将全部以相同的方式解释.因此,无论"$ {f//[^ 0-9]/}"是什么,"$ {f//[^ 0-9]/}.pdf"都将附加".pdf".
will all be interpreted in the same way. So whatever "${f//[^0-9]/}" is, "${f//[^0-9]/}.pdf" is ".pdf" appended to it.
我们处理所有神秘问题的内核:
We approach the kernel of all mysterias:
${f//[^0-9]/}
这是形式的替换表达式
${variable//pattern/replacement}
- 变量是$ f(在这里我们可以省略括号内的$)是从上面说的$ f.那很简单!
- 替换为空-更加简单.
- 但是[^ 0-9]确实很复杂,不是吗?
-
[0-9]
仅仅是从0到9的所有数字的组,其他组可能是:
is just the group of all digits from 0 to 9, other groups could be:
[0-4] digits below 5
[02468] even digits
[a-z] lower case letters
[a-zA-Z] all (common latin) characters
[;:,/] semicolon, colon, comma, slash
第一个字符前面的插入符号^是该组的否定字词
The Caret ^ in front as first character is the negation of the group:
[^0-9]
表示组中除0到9之外的所有内容(包括点,逗号,冒号等).一起:
means everything except 0 to 9 (including dot, comma, colon, ...) is in the group. Together:
${f//[^0-9]/}
从$ f中删除所有非数字,然后
remove all non-digits from $f, and
"${f//[^0-9]/}.pdf"
附加.pdf-全部内容都被屏蔽.
append .pdf - the whole thing masked.
${v//p/r}
及其朋友(有很多用处)在Parameter Expansion
章的man bash
中进行了说明.对于这个小组,我没有可供进一步阅读的资料.
and its friends (there are many useful) are explained in man bash
in the chapter Parameter Expansion
. For the group I don't have a source for further reading at hand.