如何删除文件名开头的数字,短划线和下划线

MAP*_*APK 1 unix linux bash filenames

我有成千上万的MP3文件,但所有的不寻常的文件名,例如 1-2songone.mp3,2songtwo.mp3,2_2_3_songthree.mp3.我想删除这些文件开头的所有数字,破折号和下划线并获得结果:

songone.mp3
songtwo.mp3
songthree.mp3
Run Code Online (Sandbox Code Playgroud)

Ben*_* W. 5

这可以使用扩展的globbing来完成:

$ ls
1-2songone.mp3  2_2_3_songthree.mp3  2songtwo.mp3
$ shopt -s extglob
$ for fname in *.mp3; do mv -- "$fname" "${fname##*([-_[:digit:]])}"; done
$ ls
songone.mp3  songthree.mp3  songtwo.mp3
Run Code Online (Sandbox Code Playgroud)

这使用参数扩展:${fname##pattern}从头开始删除最长的匹配fname.作为模式,我们使用*([-_[:digit:]]),其中*(pattern)代表"零或多个模式匹配",实际模式是hyhpens,下划线和数字的括号表达式.

备注:

  • --mv显示对选项的结束move,并确保开头的文件名-不会被解释为选项.

  • *()表达需要的extglob壳选项.正如所指出的,如果你以后不想要扩展的globs,你必须再次取消它shopt -u extglob.

  • 按照戈登戴维森的评论是:这会揍文件,如果你有,例如,像1file.mp32file.mp3.为避免这种情况,您可以使用mv -i(或--interactive),它会在覆盖文件之前提示您,或者mv -n(或--noclobber),它将不会覆盖任何文件.

  • triplee指出,如果它们不以斜线,下划线或数字开头,则会不必要地将文件移动到自身上.为避免这种情况,我们只能迭代匹配的文件

    for fname in [-_[:digit:]]*.mp3; do mv -- "$fname" "${fname##*([-_[:digit:]])}"; done
    
    Run Code Online (Sandbox Code Playgroud)

    这确保有重命名的东西.