我正在寻找两个重命名俏皮话来管理我的音乐库。
首先涉及文件名。我想使用尽可能简单的名称,即:%track %title.ext
例如01 Song name.mp3
13 Song title.flac
等。我当前使用连字符作为分隔符(在曲目编号和歌曲标题之间),我认为这是多余的。
第二个涉及文件夹名称,我需要将一些模式
从切换GENRE - Styles - ARTIST - Album (Year)
为 到GENRE - Styles - ARTIST - Year Album
(切换年份和专辑部分也省略括号)
(我用ksh88运行 openbsd 。)
这是我为文件名情况编写的最接近的一行:
for f in * ; do mv "$f" "$(print "$f" | sed "s/ - / /")" ; done
但它还不起作用。我想这与命令的第二个参数(目标)的正确封装有关mv
(编辑:添加了引号$( ... )
并且它有效,这是我没想到的)
$pwd
/home/media/E - Chanson Française/CHANSON - Chanson Française - CHARLES TRENET - Le meilleur de Charles Trenet
$l -1
01 - Boum!.flac
02 - La route enchantée.flac
03 - Ah! Dis, Ah! Dis, Ah! Bonjour!.flac
04 - La vie qui va.flac
05 - Quand j'etais p'tit.flac
06 - Ménilmontant.flac
07 - Tout me sourit.flac
08 - Le oiseaux de Paris.flac
...
$for f in * ; do mv "$f" "$(print "$f" | sed 's/ - / /')" ; done
$l -1
01 Boum!.flac
02 La route enchantée.flac
03 Ah! Dis, Ah! Dis, Ah! Bonjour!.flac
04 La vie qui va.flac
05 Quand j'etais p'tit.flac
06 Ménilmontant.flac
07 Tout me sourit.flac
08 Le oiseaux de Paris.flac
...
我认为嵌套双引号会产生错误,但它有效。这样,第一个案例就解决了。
文件夹名称的大小写更让我回避。以下是我想更改的名称示例:
$ ls -1
...
ELECTRO - Cyberpunk - CARPENTER BRUT - Blood Machines (2020)
ELECTRO - Cyberpunk - CARPENTER BRUT - Leather Teeth (2018)
ELECTRO - Cyberpunk - CARPENTER BRUT - Leather Terror (2022)
ELECTRO - Cyberpunk - CARPENTER BRUT - Trilogy (2015)
...
REGGAE - Roots - GROUNDATION - Each One Teach One (2001)
REGGAE - Roots - GROUNDATION - Hebron Gate (2002)
REGGAE - Roots - GROUNDATION - Upon the Bridge (2006)
REGGAE - Roots - GROUNDATION - Young Tree (1999)
...
结果应该是这样的:
$ ls -1
...
ELECTRO - Cyberpunk - CARPENTER BRUT - 2015 Trilogy
ELECTRO - Cyberpunk - CARPENTER BRUT - 2018 Leather Teeth
ELECTRO - Cyberpunk - CARPENTER BRUT - 2020 Blood Machines
ELECTRO - Cyberpunk - CARPENTER BRUT - 2022 Leather Terror
...
REGGAE - Roots - GROUNDATION - 1999 Young Tree
REGGAE - Roots - GROUNDATION - 2001 Each One Teach One
REGGAE - Roots - GROUNDATION - 2002 Hebron Gate
REGGAE - Roots - GROUNDATION - 2006 Upon the Bridge
...
我想我需要使用 awk 来切换字段:类似for f in *CARPENTER\ BRUT* ; do mv "$f" "$( print "$f" | awk ... )" ; done
- 用 awk 切换最后一个连字符后的年份,并可能用 tr 删除括号 - 但我在这一点上学习有困难。
如果可以安装 zsh:
XX - title.flac
到XX title.flac
常规文件。GENRE - Styles - ARTIST - Album (Year)
到GENRE - Styles - ARTIST - Year Album
目录如果满意,请删除
-n
(试运行)。如果您无法安装 zsh,您可以使用
find
和perl
来获得类似以下内容的内容:XX - title.flac
到XX title.flac
常规文件GENRE - Styles - ARTIST - Album (Year)
到GENRE - Styles - ARTIST - Year Album
目录并删除
print qq(...)
周围的rename()
如果快乐。但要注意的是:
zmv
,因此它最终可能会覆盖现有文件。使用 OpenBSD 的 ksh 和基本 POSIX 实用程序来完成此操作是可能的,但非常笨重:
可能:
XX - title.flac
到XX title.flac
常规文件。GENRE - Styles - ARTIST - Album (Year)
到GENRE - Styles - ARTIST - Year Album
目录(
print -r
如果高兴则删除)。与该
perl
方法有相同的注意事项,尽管-i
传递的选项有助于避免数据丢失(如果目标文件存在并且是目录类型,则不是从移动到移动到mv
的事实)。mv
关于您的尝试:
sed
是一个文本实用程序,并且是基于行的,而文件路径不能保证包含文本,更不用说单行文本,因此最好避免处理文件名的文件路径。print
,就像echo
默认情况下接受选项的许多实现一样(其中一些可能会导致执行任意命令,尽管 OpenBSD 的 ksh 实现似乎并非如此)并执行一些反斜杠转义序列扩展。要逐字输出文本(后跟换行符,因此它以有效行结尾),您需要print -r - "$text"
或print -r -- "$text"
,特别是如果您不能保证不会$text
以 开头-
。$(...)
) 不加引号, split+glob 最终将应用于结果。是的,你可以引用它。如果您使用已弃用的命令替换形式,嵌套引用只会成为问题`...`
,但即使如此,它也是可能的,只是使用cmd1 "`other-cmd \" $var \"`"
.$(...)
会删除所有尾随换行符,因此通常会删除太多字符。--
之后也失踪了mv
。mv
即使sed
没有修改文件路径,您也会调用。for i in *
,如果当前工作目录中没有非隐藏文件,则循环中仍然会有一个路径作为*
文件名。zsh
会zmv
报告有关不匹配文件的错误。(#q.)
===-type f
和(#q/)
===-type d
)。