如何创建一个脚本或命令行来增加我的文件名称的变量部分(但其中一些)?

如何创建一个脚本或命令行来增加我的文件名称的变量部分(但其中一些)?

我有几个名称不正确的文件:

$ ls
devoirNote1_1_2.R  devoirNote1_1_5.R  devoirNote1_4_1.R
devoirNote1_1_3.R  devoirNote1_1.R    devoirNote1.R
devoirNote1_1_4.R  devoirNote1_2_1.R  example140.R

我想devoirNote1_i_j.R用 i 和 j 整数更改除devoirNote1_4_1.Rto之外的所有内容devoirNote1_{i+1}_j.R(仅devoirNote1_4_1.R保持不变)。

我想过使用mv类似的命令mv devoirNote1_*_2.R devoirNote1_2_2.R,但是当多个文件匹配时(例如,如果 和devoirNote1_1_2.RdevoirNote1_3_2.R存在),它会产生一个问题。

因此,如何创建一个脚本或命令行来重命名我的文件,通过增加文件名中的变量之一而不是全部变量?

答案1

Perl 的rename实用程序(*)可用于此目的。它将给定的 Perl 命令应用于每个给定的文件名,并将文件重命名为命令将名称更改为的任何名称。

因此,这将更改为_1_glob_2_匹配的所有文件。

rename 's/_1_/_2_/' devoirNote1_*_2.R

可以通过/e修改替换命令来完成数字递增,使替换部分成为 Perl 片段而不是文字。

rename -v 's/_(\d+)_/"_" . ($1 + 1) . "_"/e' devoirNote1_*_2.R

这将选择文件名中下划线之间包含数字的部分,将数字捕获到$1,并将其替换为增加的数字,并将下划线添加回来。-v对于详细模式。使用示例中的文件列表,这将按devoirNote1_1_2.R renamed as devoirNote1_2_2.R预期打印。

受影响的文件是命令行末尾的 glob 匹配的文件。

但请注意,如果您有,例如1_1_21_2_2,则重命名第一个将会失败,因为它会与下一个发生冲突。这需要以相反的顺序给出文件名,或者先将它们更改为某种不冲突的形式,然后再更改回来,例如通过添加额外的字符。

(* 不是 util-linux 重命名工具。请参阅这里这里

答案2

一个脚本对于两次(批量)移动来说是多余的。使用该mmv实用程序:

mmv devoirNote1_2_"*" devoirNote1_3_#1
mmv devoirNote1_1_"*" devoirNote1_2_#1

当然按照这个顺序。如果有两个以上的动作,那么脚本确实会更好。

答案3

在这里,我们使用过滤器从搜索列表中negative lookaheads过滤出文件。*Note1_3_2.R*Note1_4_2.R

OP 想要保持*Note1_4_2.R原样=>我们也不能碰之前的一个文件,即 ,*Note1_3_2.R因为我们没有地方可以 mv 这个。

循环for逻辑对 1 和 2 之间的索引号执行 a ,reverse numeric sort以便我们可以执行非破坏性的 mv 操作。

perl -e '
   /(.*)_(\d+)_(.*)/ and
      rename $_, join "_", $1, $2+1, $3 or warn "Could not mv the file <<$_>>\n"
      for
         map  {                  $_->[0]                   }
         sort { $b->[2] <=> $a->[2] || $b->[1] <=> $a->[1] }
         map  {             [$_, /_(\d+)_(\d+)/]           }
         grep {     /^devoirNote1_(?![34]_1.R)\d+_\d+.R/   }
         <*.R>
'

相关内容