使用 sed 重命名文件时出现奇怪的输出

使用 sed 重命名文件时出现奇怪的输出

我正在使用Ubuntu 20.04.2GNU sed version 4.7我有一堆音乐文件,它们的命名很奇怪,因为它们没有我指定在文件名中的所有信息。例如,“Bruno Mars - NA - Bruno Mars - The Lazy Song.aiff”基本上,NA 代替了年份,因为年份是未知的。我想要做的是重命名所有这些文件以省略“- NA -”及其之前的所有内容,因此文件显示为“Bruno Mars - The Lazy Song.aiff”

这是我的问题以及我到目前为止尝试过的方法:我将一些受影响的文件复制到另一个文件夹,并使用命令sed 's/^.*NA -//' *尝试修复命名,但我开始从终端得到非常奇怪的输出,请参阅。我尝试重新安装 sed,使用rename sed 's/^.*NA -//' *perl -pi -e 's/^.*NA -//' *,但都不起作用;但是,rename 和 perl 命令没有产生与以前相同的奇怪输出。我的直觉告诉我我的正则表达式不正确,但文档说这应该有效。任何帮助都值得感激。谢谢!

答案1

该命令sed 's/^.*NA -//' *不会重命名文件,它会尝试替换文件内容中的模式,并将结果传输到终端(可能会产生奇怪的结果,特别是如果扩展*包含任何二进制文件)。

该命令perl -pi -e 's/^.*NA -//' *会执行相同的操作,但会修改内容,可能会损坏您的文件。

要使用 sed(或 perl 本身)进行文件重命名,你需要执行以下操作

for f in *; do mv -n -- "$f" "$(sed 's/pattern/replacement' <<<"$f")"

或者

for f in *; do mv -n -- "$f" "$(printf '%s\n' "$f" | sed 's/pattern/replacement')"

即通过标准输入将每个文件的名称传递给 sed。但是,您的模式可以很容易地写成 shell 替换,从而完全消除了对 sed 的需要:

for f in *; do mv -n -- "$f" "${f##* - NA - }"; done

(我假设你也想删除前导空格)。##*匹配最长的前导字符序列,相当于基本正则表达式^.*

要在后台使用 perl,但修改文件名称您需要的是renamefrom package 命令,而不是内容rename。(还有其他rename命令,例如 from package 命令util-linux,其工作方式不同。)例如:

rename -n 's/^.*? - NA - //' *.aiff

(我将范围限制为.aiff文件,并使.*匹配非贪婪 - 这是不提供的功能-以便在有多个实例的情况下sed它只匹配第一个。)一旦您对建议的重新命名感到满意,就可以删除。- NA --n

相关内容