首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Bash中,如何剥离目录中文件名中的所有数字,同时保持文件扩展名不变

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

Stack Overflow用户
提问于 2012-04-28 06:36:13
回答 1查看 1.3K关注 0票数 2

我在一个目录中有这样的文件:

代码语言:javascript
复制
asdfs54345gsdf.pdf
gsdf6456wer.pdf
oirt4534724wefd.pdf

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

代码语言:javascript
复制
54345.pdf
6456.pdf
4534724.pdf

最好是本机Bash命令或脚本(OSX 10.6.8)

我发现的一些线索包括

代码语言:javascript
复制
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 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-28 07:53:27

这个应该可以做到:

代码语言:javascript
复制
for f in *.pdf 
do 
   mv "$f" "${f//[^0-9]/}.pdf"
done

但你最好先试一下:

代码语言:javascript
复制
for f in *.pdf 
do 
   echo mv "$f" "${f//[^0-9]/}.pdf"
done

注意,abc4.pdf和zzz4.pdf都将重命名为4.pdf。所以也许你可以使用mv -i而不仅仅是mv。

更新:解释:

我想第一部分已经很清楚了;*.pdf被称为.pdf,它匹配所有文件,以globbing结尾。for f in ...只是遍历它们,每次都将f设置为其中一个。

代码语言:javascript
复制
for f in *.pdf 
do 
   mv "$f" "${f//[^0-9]/}.pdf"
done

我猜

代码语言:javascript
复制
mv source target 

这一点也很清楚。如果一个文件被命名为"Unnamed File1",你需要用引号来掩蔽它,因为否则mv将会是

代码语言:javascript
复制
mv Unnamed File1 1.pdf 

这意味着,它有多个要移动的文件,Unnamed和File1,并将1.pdf解释为要将这两个文件移动到的目录。

好吧,我想真正的问题在这里:

代码语言:javascript
复制
"${f//[^0-9]/}.pdf"

有一个字符的外部粘合。顺其自然吧

代码语言:javascript
复制
 foo=bar

然后进行一些变量赋值

代码语言:javascript
复制
 $foo
 ${foo}
 "$foo"
 "${foo}"

有四种指代它们的合法方式。后两个用于掩蔽空白等,所以这在某些情况下是没有区别的,在某些情况下是。

如果我们把一些东西粘在一起

代码语言:javascript
复制
 $foo4
 ${foo}4
 "$foo"4
 "${foo}"4

第一种形式不起作用--外壳程序将查找变量foo4。所有其他3个表达式都引用bar4 -首先将$foo解释为bar,然后附加4。对于某些字符,不需要掩码:

代码语言:javascript
复制
 $foo/fool
 ${foo}/fool
 "$foo"/fool
 "${foo}"/fool 

都将以相同的方式被解释。因此,无论"${f//^0-9/}“是什么,"${f//^0-9/}.pdf”都是附加在它后面的".pdf“。

我们接近所有奥秘的核心:

代码语言:javascript
复制
${f//[^0-9]/}

这是以下形式的替换表达式

代码语言:javascript
复制
${variable//pattern/replacement}

  • 变量是$f (我们可以在这里省略括号内的$)是上面的$f。这很简单!
  • 替换是空的-那就更容易了。
  • 但是^0-9是非常复杂的东西,不是吗?

-

代码语言:javascript
复制
[0-9] 

只是从0到9的所有数字的组,其他组可以是:

代码语言:javascript
复制
[0-4] digits below 5
[02468] even digits
[a-z] lower case letters 
[a-zA-Z] all (common latin) characters 
[;:,/] semicolon, colon, comma, slash

前面的加号^作为第一个字符是组的否定:

代码语言:javascript
复制
[^0-9] 

表示除0到9之外的所有内容(包括点、逗号、冒号、...)就在这个群里。合在一起:

代码语言:javascript
复制
 ${f//[^0-9]/}

从$f中删除所有非数字,然后

代码语言:javascript
复制
"${f//[^0-9]/}.pdf"

追加.pdf -整个过程都被屏蔽了。

代码语言:javascript
复制
 ${v//p/r}

它的朋友(有很多有用的)在Parameter Expansion一章中用man bash进行了解释。对于这个小组,我手头没有进一步阅读的来源。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10358766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档