我有一些文件夹,里面有专辑年份和一堆我不关心的文本,我想删除/重命名它们。以下是我对以下文件所做的尝试:
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
这里不需要全局替换标志,因为每个文件只进行一次替换。