Bash脚本重命名多个文件

4

假设我有一堆文件,它们的名称类似于:bsdsa120226.nai bdeqa140223.nai,我想将它们重命名为120226.nai 140223.nai。如何使用下面的脚本实现这一目标?

#!/bin/bash
name1=`ls *nai*`
names=`ls *nai*| grep -Po '(?<=.{5}).+'`
for i in $name1
    do
    for y in $names
        do
            mv $i $y
        done
    done



Solution:
name1=`ls *nai*`

for i in $name1
do
y=$(echo "$i" | grep -Po '(?<=.{5}).+')
mv $i $y
done

尝试使用此代码 (?<=^.{5}).+ - Avinash Raj
1
@AQT,把一个_答案_放在你的问题中有点毫无意义,这似乎破坏了整个问答概念。只需接受您认为正确的答案即可。如果没有答案,并且您有一个答案,请将其作为答案发布并接受它。 - paxdiablo
4个回答

2

This:

#!/bin/bash

shopt -s extglob nullglob
for file in *+([[:digit:]]).nai; do
    echo mv -nv -- "$file" "${file##+([^[:digit:]])}"
done

如果您对 mv 命令满意,则可以删除 echo

注意:此解决方案不会假设有5个要删除的前导字符。它将删除所有前导非数字字符。


1
仅使用bash,您可以这样做:
for file in *nai* ; do
  echo mv -- "$file" "${file:5}"
done

(满意输出后,请删除echo。)

脚本中避免使用ls,除了显示信息外。改用普通的globbing代替。

另请参阅bash如何进行字符串操作?获取更多字符串操作技巧。


你的脚本无法处理该结构:如果有5个文件,它将对第一个文件调用5次mv(每个第二个列表中的元素都会调用一次),对于第二个文件也是如此,以此类推。你需要同时迭代这两组名称。(它还无法处理文件名中的空格等问题。)

重命名命令在Centos/Redhat上是否有效? - Dynamiite
有一个重命名命令,但它并不是其他答案中提到的那种(功能更加有限,不支持正则表达式)。不过你可能可以安装它,它只是一个 Perl 脚本。 - Mat

1

在重命名文件时,你最好使用rename(在某些系统上是prename),因为它允许你使用Perl正则表达式进行重命名,例如:

prename 's/^.{5}//' *.nai

你的脚本无法正常工作的原因是,对于每个源文件,你都试图将其重命名为每个目标文件。
如果你需要限制自己只使用该脚本,你需要找出每个源文件的单个目标文件,类似于:
#!/bin/bash
for i in *.nai; do
    y=$(echo "$i" | cut -c6-)
    mv "$i" "$y"
done

0
如果您的系统有 "rename" 工具,最好使用简单的 "rename" 命令。
rename 's/^.{5}//' *.nai

它只是从文件名中删除前5个字符。

或者

for i in *.nai; do mv "$i" $(grep -oP '(?<=^.{5}).+' <<< "$i"); done

有时在某些系统上被称为“prename”(Perl重命名),以防您拥有的“rename”似乎无法正常工作。 - paxdiablo
Avinash,因此我的评论是“以防万一” :-) - paxdiablo
好的,谢谢。你有什么想法为什么我的脚本不起作用? - Dynamiite

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接