删除 fileName 末尾第一个破折号 (-) 后的字符(数字)

删除 fileName 末尾第一个破折号 (-) 后的字符(数字)

我有数千个 .mp3 文件,最近需要这些文件,并且这些文件末尾都附加了一个破折号-和一系列不同数量的数字。我想删除最后一个破折号和它右边的数字。

一些例子是:

songName-artistName-12345.mp3
songName(1973)-artistName-12345.mp3
songName-artistName12d-12345.mp3

我想要的是:

songName-artistName.mp3
songName(1973)-artistName.mp3
songName-artistName12d.mp3

我尝试过这个:

ls | sed 's/\(.*\)\(-.*\)/mv \"&\" \"\1.mp3\"/' | bash

但我一直

syntax error near unexpected token '('

我尝试过退出/,但也没多大帮助。我把所有这些歌曲都放在一个文件夹中。还有另一个包含.wav文件的文件夹。

感谢您花时间阅读!

答案1

我认为这应该可以做到:

for f in *.mp3; do
  echo "Moving $f to ${f%-[0-9]*}.mp3"
  # below the action commented
  # mv "$f" "${f%-[0-9]*}.mp3"
done

输出:

moving songName(1973)-artistName-12345.mp3 to songName(1973)-artistName.mp3
moving songName-artistName-12345.mp3 to songName-artistName.mp3
moving songName-artistName12d-12345.mp3 to songName-artistName12d.mp3

答案2

虽然这不是一个特定于 Ubuntu 的问题,但无论如何:

回想一下,shell 仍然会扩展双引号字符串内的元字符。很有可能,一些文件名可能包含 shell 元字符,例如$,这会弄乱输出,可能与语言环境的某些交互有关,并且 shellls喜欢将包含非字母数字字符的文件名放在引号中(尽管当输出是管道时它不应该这样做)。尝试使用单引号作为输出,并将 sed 参数括在双引号中。为了更好,请将语言环境重置为中性语言环境并使用ls -N

$ export LC_ALL=C
$ ls -N | sed "s/\(.*\)\(-.*\)/mv \'&\' \'\1.mp3\'/" |bash

以防您有不同的版本:

$ sed --version
sed (GNU sed) 4.4

$ bash --version
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)

答案3

您需要使中间的匹配非贪婪,否则它会吃掉您的艺术家名字:

$ printf %s\\0 *.mp3 | \
  sed -znr 's|(.*)-[^-].*\.mp3$|mv \"&\" \"\1\.mp3\"|e'

但是,重命名会快得多:

$ printf %s\\0 *.mp3 | \
  rename --null 's/(.*)-.*?\.mp3$/$1\.mp3/'

相关内容