如何通过更改文件名的一个组成部分来重命名多个文件?

如何通过更改文件名的一个组成部分来重命名多个文件?

我发现了很多有关如何使用命令行重命名多个文件的问题。但是我无法解决重命名此文件名的具体问题:

something_4M_something_something_manyothersomethings.csv

进入这个:

something_4_M_something_something_manyothersomethings.csv

我需要的是将字段拆分4M4_M但我无法做到这一点(注意:每个某物用下划线分隔,还有很多其他字段,我相信这对于任务来说并不重要)。

我所做的是以下内容,但它不起作用,正如我所期望的那样,我认为这是正则表达式的问题,但我无法找出更好的方法:

rename -n 's/.4M/$&_4_M/' *

另外,我不知道我写的东西到底是如何工作的,因为我在与此类似的问题之一的评论中发现了类似的内容,但我再也找不到它了。

答案1

如果您真正想做的只是替换4M4_M,那么您的正则表达式的变体可以执行以下操作:

$ ls
something_4M_something_something_manyothersomethings.csv
$ rename -n 's/4M/4_M/' *
'something_4M_something_something_manyothersomethings.csv' would be renamed to 'something_4_M_something_something_manyothersomethings.csv'

正则表达式适用于任何东西里面名称,因此您不需要执行特定操作来保留领先的“某物”。

如果您想做其他事情,例如将第一个“某事”移至第二个“某事”,或限制为4M下划线后第一次出现,请编辑您的问题并澄清。


正如评论中所观察到的,-n进行了一次空运行,因此它显示了会发生什么,并且实际上并不执行操作。

由于问题中的示例已经使用了-n,我假设提问者可以理解这一点。

答案2

使用 Raku(以前称为 Perl_6)

对于单个文件:

    ~$ raku -e ' \
    my $name = dir(test => /^ something_4M_somethingelse \. csv $/)[0]; \
    my $modname = S/^ something_<(4M)>_somethingelse \. csv $/4_M/.IO given $name; \
    ($name,$modname).say; \
    #rename($name,$modname, createonly => True);'

对于多个文件:

    ~$ raku -e ' \
    my @names = dir(test => /^ something_<digit><upper>_somethingelse \. csv $/); \
    my @modnames = do for @names {S/^ something_<(<digit><upper>)>_somethingelse \. csv $/$<digit>_$<upper>/.IO given $_;}; \
    for [Z] @names,@modnames -> ($x,$y) { ($x,$y).say }; \
    #for [Z] @names,@modnames -> ($x,$y) { rename($x,$y, createonly => True) };'

目录输入:

~$ ls
something_4M_somethingelse.csv  something_5N_somethingelse.csv  something_6O_somethingelse.csv

目录输出(多文件重命名):

~$ ls
something_4_M_somethingelse.csv something_5_N_somethingelse.csv something_6_O_somethingelse.csv

警告:先备份!!

简要说明(单文件重命名):dir()使用正则表达式匹配(“副词”)选项获取感兴趣的文件的列表test => / ... /,并且仅采用一个元素(无论如何[0]),将其存储在标量变量中$name。检查该变量表明它是一个.IO对象。

使用熟悉的S///习惯用法修改given $name变量,并将修改后的名称存储为$modname.请注意,这里,S///字符串化 so.IO方法调用被添加到S///so that也是$modname一个.IO对象。

在正则表达式中,不熟悉的符号可能是<(…)>表示法。但这只是Raku的捕获标记,因此虽然 的左半部分的整个匹配项S///被识别,但仅捕获4M其中的匹配项<(…)>,并在 的右半部分进行修改S///

.IO如果获得了所需的起始/结束对象,该行($name,$modname).say;应生成类似于以下内容的输出:

("something_4M_somethingelse.csv".IO "something_4_M_somethingelse.csv".IO)

一旦一切看起来都不错,您可以取消 Raku 代码最后rename()一行的注释,以实际将倒数第二行中列出的文件重命名为.say.

注意:在上面的代码createonly => True中包含副词/选项rename()意味着rename()不会破坏现有的文件名(较短的形式:createonly具有相同的作用)。删除createonly => True:createonly副词/选项以获得默认值(False即破坏)并允许重命名(覆盖)预先存在的文件/文件名。

https://docs.raku.org/syntax/S$SOLIDUS$SOLIDUS$SOLIDUS
https://docs.raku.org/routine/rename
https://raku.org

相关内容