用Bash批量重命名文件

Bash如何重命名一系列软件包以删除其版本号? 我一直在用expr%% ,无济于事。

例子:

Xft2-2.1.13.pkg变成Xft2.pkg

jasper-1.900.1.pkg成为jasper.pkg

xorg-libXrandr-1.2.3.pkg成为xorg-libXrandr.pkg

你可以使用bash的参数扩展function

 for i in *.pkg ; do mv "$i" "${i/-[0-9.]*.pkg/.pkg}" ; done 

包含空格的文件名需要引号。

如果所有文件都在相同的目录中,则按顺序排列

 ls | sed -n 's/\(.*\)\(-[0-9.]*\.pkg\)/mv "\1\2" "\1.pkg"/p' | sh 

会做你的工作。 sed命令将创build一系列mv命令,然后您可以将其导入到shell中。 最好先运行pipe道,而不用训练| sh以便validation命令是否符合你的要求。

通过多个目录recursion使用类似的东西

 find . -type f | sed -n 's/\(.*\)\(-[0-9.]*\.pkg\)/mv "\1\2" "\1.pkg"/p' | sh 

我会做这样的事情:

 for file in *.pkg ; do mv $file $(echo $file | rev | cut -f2- -d- | rev).pkg done 

假设你所有的文件都在当前目录中。 如果没有,请尝试使用哈维尔上面的build议。

编辑 :此外,这个版本不使用任何bash特定的function,如上面的其他人,这导致你更多的便携性。

更好地使用sed ,如下所示:

 find . -type f -name "*.pkg" | sed -e 's/((.*)-[0-9.]*\.pkg)/\1 \2.pkg/g' | while read nameA nameB; do mv $nameA $nameB; done 

计算正则expression式是作为一个练习(正如处理包含空格的文件名一样)

这似乎工作假设

  • 一切以$ pkg结尾
  • 你的版本#总是以“ – ”开始

剥离.pkg,然后剥离 – ..

 for x in $(ls); do echo $x $(echo $x | sed 's/\.pkg//g' | sed 's/-.*//g').pkg; done 

我有多个*.txt文件在同一个文件夹中被重命名为.sql 。 下面为我​​工作:

 for i in \`ls *.txt | awk -F "." '{print $1}'\` ;do mv $i.txt $i.sql; done 

谢谢你的答案。 我也有一些问题。 将.nzb.queued文件移动到.nzb文件。 它有文件名中的空格和其他文件,这解决了我的问题:

 find . -type f -name "*.nzb.queued" | sed -ne "s/^\(\(.*\).nzb.queued\)$/mv -v \"\1\" \"\2.nzb\"/p" | sh 

它基于Diomidis Spinellis的答案。

正则expression式为整个文件名创build一个组,并为.nzb.queued之前的部分创build一个组,然后创build一个shell移动命令。 用string引用。 这也避免了在shell脚本中创build一个循环,因为这已经由sed完成了。