Regex 使用查找和重命名以实现其预期用途

Regex 使用查找和重命名以实现其预期用途,regex,bash,find,rename,xargs,Regex,Bash,Find,Rename,Xargs,现在,在你面对手掌并点击重复条目或类似内容之前,请继续阅读,这个问题是理论和实践的 从标题上看,很明显我想做的是找到一些文件,然后重命名它们。问题是,有很多方法可以做到这一点,所以我最终决定选择一种,并试图从理论上解决它 让我来准备一下: 假设我有100个文件,所有文件的名称都类似于此Image_200x200_nnn_AlphaChars.jpg,其中nnn是一个递增的数字,AlphaChars即: 进入阶段查找。现在,通过一个简单的一行程序,我可以找到这个目录中的所有图像文件。(不确定如何做

现在,在你面对手掌并点击重复条目或类似内容之前,请继续阅读,这个问题是理论和实践的

从标题上看,很明显我想做的是找到一些文件,然后重命名它们。问题是,有很多方法可以做到这一点,所以我最终决定选择一种,并试图从理论上解决它

让我来准备一下: 假设我有100个文件,所有文件的名称都类似于此Image_200x200_nnn_AlphaChars.jpg,其中nnn是一个递增的数字,AlphaChars即:

进入阶段查找。现在,通过一个简单的一行程序,我可以找到这个目录中的所有图像文件。(不确定如何做到不区分大小写)

进入阶段重命名。就其本身而言,我们希望您执行以下操作:

rename <search> <replace> <haystack>
因此,我们的目标是让查找结果重命名原始图像名称,并将最后一个下划线之前的所有内容替换为img

是的,我知道重复会带来问题,是的,我知道名称中的空格也会让我的生活陷入地狱,甚至不会从子目录之类的开始。为了简单起见,我们讨论的是单个目录,所有文件名都是唯一的,没有特殊字符


我需要先了解基本的知识,然后才能接触核心内容。有人想帮忙吗

如果您不需要
-print0
(即您确定您的文件名不包含换行符),您可以执行以下操作:

find . -type f -name "*.jpg" | xargs rename 's/Image_200x200_(\d{3})/img/'
这对我来说很有用:

~/tmp$ touch Image_200x200_001_BlueHat.jpg
~/tmp$ touch Image_200x200_002_RedHat.jpg
~/tmp$ touch Image_200x200_100_MyCat.jpg
~/tmp$ find . -type f -name "*.jpg" | xargs rename 's/Image_200x200_(\d{3})/img/'
~/tmp$ ls
img_BlueHat.jpg  img_MyCat.jpg  img_RedHat.jpg

管道之后发生的事情是,xargs正在解析find的输出,并将其以合理的块传递给rename命令,该命令对文件名执行regex,并将文件重命名为结果


更新:起初我没有尝试使用空终止符的版本,但它也适用于我。也许您使用不同的正则表达式进行了测试?

如果您不需要
-print0
(即,您确定您的文件名不包含换行符),您可以执行以下操作:

find . -type f -name "*.jpg" | xargs rename 's/Image_200x200_(\d{3})/img/'
这对我来说很有用:

~/tmp$ touch Image_200x200_001_BlueHat.jpg
~/tmp$ touch Image_200x200_002_RedHat.jpg
~/tmp$ touch Image_200x200_100_MyCat.jpg
~/tmp$ find . -type f -name "*.jpg" | xargs rename 's/Image_200x200_(\d{3})/img/'
~/tmp$ ls
img_BlueHat.jpg  img_MyCat.jpg  img_RedHat.jpg

管道之后发生的事情是,xargs正在解析find的输出,并将其以合理的块传递给rename命令,该命令对文件名执行regex,并将文件重命名为结果


更新:起初我没有尝试使用空终止符的版本,但它也适用于我。也许您使用不同的正则表达式进行了测试?

管道之后发生了什么:

find ... -print0 | xargs -0 rename "s/Image_200x200_(\d{3})/img/"
xargs
正在读取由
find
命令生成的文件名,并重复执行
rename
命令,一次追加几个文件名。净效应将类似于:

rename '...' file001 file002 file003 file004 file005 file006 file007 file008 file009 file010
rename '...' file011 file012 file013 file014 file015 file016 file017 file018 file019 file010
rename '...' file021 file022 file023 file024 file025 file026 file027 file028 file029 file010
...
rename '...' file091 file092 file093 file094 file095 file096 file097 file098 file099 file100

find-print0 | xargs-0
是一个方便的组合,可以更安全地处理可能包含空格的文件。

管道后发生的事情:

find ... -print0 | xargs -0 rename "s/Image_200x200_(\d{3})/img/"
xargs
正在读取由
find
命令生成的文件名,并重复执行
rename
命令,一次追加几个文件名。净效应将类似于:

rename '...' file001 file002 file003 file004 file005 file006 file007 file008 file009 file010
rename '...' file011 file012 file013 file014 file015 file016 file017 file018 file019 file010
rename '...' file021 file022 file023 file024 file025 file026 file027 file028 file029 file010
...
rename '...' file091 file092 file093 file094 file095 file096 file097 file098 file099 file100

find-print0 | xargs-0
是一个方便的组合,可以更安全地处理可能包含空白的文件。

另一种方法是避免使用
重命名--bash有足够的能力:

find ... -print0 | while read -r -d '' filename; do
  mv "$filename" "img_${filename##*_}"
done

#ᜯɐ*.
部分从值中删除所有前导字符,包括最后一个下划线。

另一种方法是避免使用
rename
--bash足够:

find ... -print0 | while read -r -d '' filename; do
  mv "$filename" "img_${filename##*_}"
done

##*.
部分从值中删除所有不超过并包括最后一个下划线的前导字符。

对于大小写不敏感,请使用
-iname
而不是
-name
。如果知道文件位于单个目录中,请删除
查找
<当目标文件分散在一个目录层次结构中时,code>find
是完美的,但在一个目录中就可以找到。然后你有:
rename“s/Image\u 200x200”(\d{3})/img/”*.jpg
我喜欢简化,谢谢@glenn jackman,但是这个查找重命名显然会变得更复杂,因此我使用find,因为下一步就是这样做,递归地查找和替换文件并重命名它们,后来,名字或特殊字符中的空格会变得很难看。。。但简单的basic很重要,首先是:)@glen jackman使用建议的
重命名的s/Image\u 200x200(\d{3})/img/'*。jpg
在CentOS 5.5上不起任何作用。执行
重命名Image\u 200x200\uimg\u*.jpg
虽然有效,但如果没有正则表达式,这可能是问题所在…对于大小写不敏感,请执行
-iname
而不是
-name
。如果您知道文件位于单个目录中,请放弃
查找
<当目标文件分散在一个目录层次结构中时,code>find
是完美的,但在一个目录中就可以找到。然后你有:
rename“s/Image\u 200x200”(\d{3})/img/”*.jpg
我喜欢简化,谢谢@glenn jackman,但是这个查找重命名显然会变得更复杂,因此我使用find,因为下一步就是这样做,递归地查找和替换文件并重命名它们,后来,名字或特殊字符中的空格会变得很难看。。。但简单的basic很重要,首先是:)@glen jackman使用建议的
重命名的s/Image\u 200x200(\d{3})/img/'*。jpg
在CentOS 5.5上不起任何作用。执行
重命名Image\u 200x200\uimg\u*.jpg
虽然有效,但如果没有正则表达式,这可能是问题所在…我只是在我的框上一步一步地尝试,但什么都没有发生。这就是为什么我问这个问题,因为我认为我做错了什么。使用Linux CentOS-55-64-minimal 2.6.18-274.17.1.el5#1 SMP GNU/Linux with/usr/bin/renameOdd,我在debian上进行测试,使用
perl-5.10.1
包中的
rename
findutils
版本
4.4.2-1+b1
<代码>Linux 2.6