在Unix中使用正则表达式批量重命名文件

在Unix中使用正则表达式批量重命名文件

我有几千个以下形式的文件:

[8位数字]_[我想要的号码]_S60491_I129111.dcm。

我希望删除除我想要的数字之外的所有内容,并将其用作其名称。在 Ruby 中,我可以使用正则表达式获取该值/^.*_(\d+)_S60491_I12911.dcm/,但我无法将其转换为sed允许我用下划线之间的数字替换完整文件名的表达式。

有没有办法使用sed或其他基本 Bash 命令来做我想做的事情?如果有帮助的话,我想要的数字只是一个计数器(即从 1 到 2100),并且前缀 8 位数字恰好导致文件按正确顺序列出(即从文件 1 到文件 2100),所以我可能想得太多了。

答案1

这对我有用:for a in * ; do mv "$a" $(echo "$a" | cut -d'_' -f 2) ; done

蟾蜍:/home/hennes/work/foo>ls -l
共 0
-rw------- 1 个用户 0 1 月 23 日 22:19 12345678_023454_S60491_I129111.dcm
-rw------- 1 个用户 0 1 月 23 日 22:19 12345678_123454_S60491_I129111.dcm
-rw------- 1 个用户 0 1 月 23 日 22:19 12345678_123456_S60491_I129111.dcm

toad:/home/hennes/work/foo>for a in *;执行 mv $a $(echo $a | cut -d'_' -f 2);完成

蟾蜍:/home/hennes/work/foo>ls -l
共 0
-rw------- 1 个用户 0 1 月 23 日 22:23 023454
-rw------- 1 个用户 0 1 月 23 日 22:23 123454
-rw------- 1 个用户 0 1 月 23 日 22:23 123456

for a in *选择所有文件。如果文件较多,可以使用 *.dcm 代替。

mv(移动)改变文件名

来自 $a (选择的文件名)

到名称的字段2,_使用字段分隔符。

请注意,此脚本将移动文件,因此旧文件名将丢失。您可以使用“cp”而不是“mv”来制作副本。

如果要保留扩展名,请将其添加到 -f 2) 之后。
例如 for a in * ; do cp $a $(echo $a | cut -d'_' -f 2).dcm ; done

答案2

有一种工具通常名为改名prename安装在大多数系统上。在我的 Debian/Ubuntu 系统上,它是 Perl 的一部分。它允许您使用 Perl 样式的正则表达式以您喜欢的方式操作文件名。

您的命令可能看起来像这样。我建议您--no-act在实际进行任何更改之前传递该选项并检查输出。

prename 's/^.*_(\d+)_S60491_I12911.dcm/$1/' *

答案3

因为我们知道名称的格式并且不包含空格:

for a in * ; do
   mv $a $(echo $a | sed 's/[^_]*_//;s/_S60491_I129111.dcm//')
done

答案4

有很多方法可以完成此操作。但是既然您要求了sed,那么可以这样做:

lsdcm | sed 's/^([0-9]{8}_([0-9])_S60491_I129111.dcm)/mv \1 \2 /g' | bash

模式的第一位选择 8 位数字,然后查找任何数字(因为您没有提到第二个数字的大小),然后查找尾随序列。\1\2引用外部和内部转义括号的内容\(...\)。在这种情况下,您可以用任何 shell 替换bash

sed 的 GNU 扩展还允许您执行以下操作:

ls *dcm | sed 's/^([0-9]{8}_([0-9]+)_S60491_I129111.dcm)/mv \1 \2 /g' | bash

where+允许匹配一个或多个,而 where*匹配零个或多个,这会给 带来问题12345678__S60491_I129111.dcm

相关内容