我有一个目录,其中包含一堆文件,其名称如下:
- 通用名称- dd -01 _.txt
- 通用名称- dd -02 _.txt
- 通用名称- dd -03 _.txt
- 通用名称- dd -04 _.txt
我想重命名所有这些,只保留数字和扩展名,如下所示:
- 01.txt
- 02.txt
- 03.txt
- 04.txt
我如何使用 shell 脚本来做到这一点?
答案1
Perl重命名
我会使用(perl-)重命名。发行版提供两种类型的重命名,因此您可以检查是否安装了 perl 版本的重命名
$ rename --version
perl-rename 1.9
运行它来-n
测试该命令作为“试运行”。
$ rename 's/[^0-9]*([0-9]*).*/\1.txt/' * -n
generic name- dd -01 _.txt -> 01.txt
generic name- dd -02 _.txt -> 02.txt
generic name- dd -03 _.txt -> 03.txt
generic name- dd -04 _.txt -> 04.txt
当您高兴时运行命令本身。
$ rename 's/[^0-9]*([0-9]*).*/\1.txt/' *
解释
rename 's/foo/bar/' *
:重命名所有文件 (*
),将正则表达式替换foo
为bar
.[^0-9]*([0-9]*).*
:匹配所有非数字字符[^0-9]*
,后跟数字字符,数字字符包含在“捕获组”中([0-9]*)
,后跟其余字符.*
。这将匹配整个文件名。\1.txt
:将文件名替换为捕获的组\1
,并附加.txt
.
另一个重命名
如果您安装了更简单的重命名,您将看到类似的内容。
$ rename --version
rename from util-linux 2.33.1
在这种情况下,您可以使用以下两个命令:
$ rename 'generic name- dd -' '' *
$ rename ' _' '' *
但我强烈建议学习 perl-rename。
答案2
我们可以用下面的一张衬垫来做。测试了一下。但它需要从文件所在的当前文件夹执行。
for file in *generic*.txt; do newname=$(echo $file | awk -F"-" '{print $3}' | sed 's/ _//g'); mv "$file" $newname;done
如果你想从不同的文件夹运行,你可以尝试使用下面的脚本
#!/bin/bash
SRCFLDR=yoursourcefolder
for file in $SRCFLDR/*generic*.txt;do
newname=$(echo $file | awk -F"-" '{print $3}' | sed 's/ _//g')
mv "$file" $newname
echo $file has been renamed to $newname
done
答案3
这个简单的脚本应该可以做到这一点:
for f in *[0-9]*.*; do
base=${f%.*}
mv -- "$f" "${base//[^0-9]}.${f##*.}"
done