使用Bash脚本重命名多个文件


27

我想使用Bash脚本重命名同一目录中的多个文件。文件名如下:

file2602201409853.p
file0901201437404.p  
file0901201438761.p  
file1003201410069.p  
file2602201410180.p

我想重命名为以下格式:

file2503201409853.p
file2503201437404.p  
file2503201438761.p  
file2503201410069.p  
file2503201410180.p

我正在阅读有关重命名命令的内容,并尝试通过这种方式进行操作,但是它没有任何作用,我认为我对语法有疑问。然后我读到您可以使用mv命令进行循环,如下所示:

for file in cmpsms*2014*.p; do
    mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}"
done

但是我无法重命名文件。我究竟做错了什么?



2
参数扩展替换表达式的右侧不能有模式表达式。您期望那*是什么?
kojiro 2014年

@Kiwy该问题与删除文件名的一部分有关。因此,高度怀疑地重复。
CVn 2014年

2
下次,请描述您要更改的文件名(在看到差异和相似之前,我必须公平地看一下它)。例子很好,但是描述例子都更好。
CVn 2014年

Answers:


42

您首先考虑重命名是正确的。如果您不习惯使用正则表达式,则语法会有些奇怪,但是一旦您知道自己在做什么,它就是最快/最短的途径:

rename 's/\d{4}/2503/' file*

只需匹配前4个数字,然后将它们交换为您指定的数字。

并使用您的文件名进行测试(-vn意味着很冗长,但什么也不):

$ rename 's/\d{4}/2503/' file* -vn
file0901201437404.p renamed as file2503201437404.p
file0901201438761.p renamed as file2503201438761.p
file1003201410069.p renamed as file2503201410069.p
file2602201409853.p renamed as file2503201409853.p
file2602201410180.p renamed as file2503201410180.p

8
请注意,这是在Debian及其衍生产品(Ubuntu,Mint等)上的Perl重命名。在其他Linux发行版中,rename是一个完全不同的文件重命名工具(Debian附带了该工具rename.ul)。
吉尔(Gilles)'所以

如果您的分布式缺乏此类工具,请查看@Michael Campbell答案。我认为rename像debian一样,每个分布式替换默认值都一样。
2015年

25

这应该可以解决问题:

for f in file*; do mv $f ${f/${f:4:8}/25032014}; done

它将第4个和第12个字符之间的字符串替换为“ 25032014”。


for f in file*; do mv $f ${f/${f:4:4}/2503}; done也可以。
Avinash Raj

真好。如果您只想用常规单词替换单词,它的作用就像sed。例如for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
埃里克(Eric)

1
@Eric-我发布了您的答案作为替代,因为我认为它更清晰,更优雅。如果您还想将其发布为答案-我将删除我的。谢谢!
Yehosef 2015年

为什么缺少双引号
通配符

它给了我一个错误:“ MV:目标'FILE_NAME'不是目录”
Aubrey

10

这确实是@Eric从上面的答案-但这是一个优雅的答案,因此我将其重新发布为适当的答案,以引起更多关注。

for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done

1
ptrn='file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p'
path=/dir
( set -- "${path}/"${ptrn} ; for f ; do {
    echo "mv ${path}/${f} \
        ${path}/file25032014${f#2014}" 
} ; done )

这应该可以解决问题。注意-我没有交出大量mv命令的习惯-如所写,这只是回声。您必须先对其进行分类,然后才能起作用。


1

一种简单的本机方法,无需遍历目录即可遍历目录

find -type f | xargs -I {} mv {} {}.txt

它将重命名每个文件。

下面是带有并行化的工作示例:

find -name "file*.p" | parallel 'f="{}" ; mv -- {} ${f:0:4}2503${f:8}'

这是想出更好解决方案的简便方法。如果您想使用有效的命令,请执行以下操作:
dtrckd 2015年

find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'
dtrckd

0

如果发现您经常做这种事情,请查找“ rename.pl”。这是一个perl脚本,但是允许您简单地将其输入perl代码(如as /// expression),并且它将基于该表达式或代码进行批量重命名。

这里有一个基本版本:http : //stackoverflow.org/wiki/Rename.pl, 但是网上还有其他版本。它已经存在了很多年了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.