重命名特定文件

重命名特定文件

我需要重命名目录中的文件,例如

11-Vnnn_S2_L001_aaa_bbb_ccc_ddd.ext

Vnnn.ext

有没有办法basename在 Linux 中使用命令来做到这一点?

我对编码非常陌生,所以我很乐意提供一些解释。

答案1

一个简单的循环:

for name in *.ext; do 
    newname=${name%%_*}.ext
    newname=${newname#*-}
    echo mv -- "$name" "$newname"
done

这将循环遍历.ext当前目录中以结尾的所有名称(因此首先更改为有问题的目录)。对于每个这样的名称,newname变量首先设置为名称的第一个_字符之前的部分,并.ext添加到末尾。-然后删除第一个字符之前的值以创建最终newname值。

这里使用的两个参数替换${variable%%pattern}和分别从值的末尾${variable#pattern}删除最长的匹配子字符串,从开头删除最短的匹配子字符串。pattern$variable

运行该echo命令以查看它是否执行正确的操作,然后删除echo前面的mv内容以实际重命名文件。

答案2

您可以尝试使用rename

rename 's/^[^-]+-([^_]+).+(\.[^.]+)$/$1$2/' *.ext

-将提取第一个和第一个之间的部分_,并将扩展名附加到其中。先尝试rename -n '...'一下,满意后删除-n

该语法使用捕获组将原始文件名分解为

  • 从开始到第一个-:的所有内容^[^-]+-,即以一个或多个字符开头的字符串不是 -,接着是一个-
  • 一个“捕获组”,包含此后的所有内容,直到但不包括第一个_: ([^_]+),即一个或多个不是的字符- 实际值稍后可以在替换文本中_引用$1
  • 之后的一切,直到但不包括最后的 ..+实际上只意味着“一个或多个任何类型的字符” - “直到最后.”的含义来自最后一部分的定义
  • 一个“捕获组”,包含最后一个.以及之后直到字符串结尾的所有内容:(\.[^.]+)$- 此公式强制捕获组内容以文字开头.,然后仅包含以下字符不是 .,直到字符串末尾$;只有这样才能确保前一组吞噬除最后一组之外的所有内容.。同样,实际内容稍后可以引用为$2(因为它是正则表达式中的第二个捕获组)。

然后,替换文本仅包含两个捕获组的实际内容:$1$2

答案3

与 AdminBees 解决方案类似,也许您更容易适应其他问题,您可以使用 bash 内置功能,如下所示:

for file in *
do
    if [[ "$file" =~ ^[^-]*-([^_]+)_.*\.ext$ ]]
    then
        mv "$file" "${BASH_REMATCH[1]}.ext"
    fi
done

那有什么作用:

for 多变的 in 空格分隔的项目列表

循环遍历列表中的每个项目,设置多变的do并执行和之间的命令done

办法当前目录中的每个文件, 尝试echo *[[是 bashs 旧test命令的内置版本:文档

现在来解压这个复杂的正则表达式:

^-输入行的开头 其次是[^-]-任何字符,除了 -, *-重复任意次数,随后是-.现在,之间的部分()就是您感兴趣的部分。Bash 将括号之间匹配的部分保存到数组中BASH_REMATCH (关联)。其正则表达式是[^_]+,意思是任何字符,除了 _,至少重复一次,随后是_.

.-任何字符*重复任意次数*,后跟\.文字.(请参阅这里),然后是ext$输入结束(行)

由于输入是我们的文件名,因此提取-和之间的第一部分_并将其保存到${BASH_REMATCH[1]}.如果输入文件名与该模式匹配,我们只需使用常规的 oldmv重命名$fileour_matched_part.ext,如果您的文件名不包含空格,则引号并不是绝对必要的,但这是一个很好的做法。

希望有帮助!

编辑:啊,废话。 AdminBee 编辑了他们的帖子,我没有看到。那好吧...

*-something_*.extEDIT2:您可以通过添加更多文字部分(例如数字)来进一步限制正则表达式仅重命名特定文件,而不是每个文件[0-9]+

答案4

ls  11-Vnnn_S2_L001_aaa_bbb_ccc_ddd.ext| awk -F "[-_]" '{print "mv " $0" "  $2".ext"}' |sh

测试并运行良好

相关内容