在 Bash 中,如何删除目录中文件名中的所有数字,同时保持文件扩展名不变

2023-12-27

我的目录中有这样的文件:

asdfs54345gsdf.pdf
gsdf6456wer.pdf
oirt4534724wefd.pdf

我想将所有文件重命名为数字 + .pdf,因此上述文件将重命名为:

54345.pdf
6456.pdf
4534724.pdf

最好的是本机 Bash 命令或脚本 (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

但你最好先尝试一下:

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。对于该小组,我手头没有进一步阅读的资源。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Bash 中,如何删除目录中文件名中的所有数字,同时保持文件扩展名不变 的相关文章

随机推荐