在 Linux 中重命名文件夹并删除“(”后的所有字符

在 Linux 中重命名文件夹并删除“(”后的所有字符

我有一些文件夹,里面有专辑年份和一堆我不关心的文本,我想删除/重命名它们。以下是我对以下文件所做的尝试:

Calvin Harris - This Is What You Came For (2016) [MP3-320]

rename 's/(*//g' *

我收到以下错误:

Unterminated '(*...' construct in regex; marked by <-- HERE in m/(* <-- HERE / at line 1, in: s/(*//g

我知道我肯定遇到了特殊字符问题。我怎样才能重命名“(”字符后的所有内容,使其看起来像这样:

Calvin Harris - This Is What You Came For

答案1

Bash 中的 shell 参数扩展mv在一个for ...环形:

for f in */; do [ -d "${f/ (*/}" ] || echo mv -nv -- "$f" "${f/ (*/}"; done

... where*/只会扩展到目录(不是文件),[ -d "${f/ (*/}" ] ||并将阻止移动到名称与目标新名称匹配的其他目录(如果存在),并且还将阻止mv尝试将目录移动到其自身下的子目录中,从而强制执行重命名操作。

注意 echo是为了安全的试运行,当对输出满意时,您需要将其删除,以便进行实际重命名...请参见下面的演示:

$ ls
'Calvin Harris - This Is What You Came For (2016) [MP3-320]'
$
$ for f in */; do [ -d "${f/ (*/}" ] || mv -nv -- "$f" "${f/ (*/}"; done
renamed 'Calvin Harris - This Is What You Came For (2016) [MP3-320]' -> 'Calvin Harris - This Is What You Came For'
$
$ ls
'Calvin Harris - This Is What You Came For'

答案2

要强制将特殊字符视为正则表达式中的文字字符,您可以对其进行转义\(或将其放在括号表达式 [(]

但是,\(*将匹配零个或多个字符的序列(。你似乎想要匹配单个( 其次是零个或多个随意的字符,即\(.*[(].*。如果您还想删除前导空格字符,则为\(.*。因此

$ rename -n 's/ \(.*//' -- *
rename(Calvin Harris - This Is What You Came For (2016) [MP3-320], Calvin Harris - This Is What You Came For)

如果你尝试重命名文件请记住,这也会删除任何文件扩展名。因此,您可能希望匹配零个或多个非字符],后跟\]

rename -n 's/ \([^]]*\]//' -- *

或者(也许更美观)

rename -n 's/ [(][^]]*[]]//' -- *

请注意,g这里不需要全局替换标志,因为每个文件只进行一次替换。

相关内容