我需要识别包含字符串‘’的音乐播放列表文件.m3u中的行,并通过特定的更改更新这些行。
例如:
/music/Miles Davis/1959 - Kind of Blue [LD]/Miles Davis - So What.mp3
需要成为:
/music/_lossless/Miles Davis/1959 - Kind of Blue/Miles Davis - So What.mp3
即。字符串'_lossless/‘被插入在'/ music /’之后,字符串‘’将从音乐文件路径中删除。
我使用for循环文件,因为有许多其他进程需要在每个文件上执行。
for f in *.m3u;
do
# I can identify the lines using:
fgrep -n "[LD]" "$f"
# I can grab the line number using:
ld_line=$(fgrep -c "[LD]" "$f")
# and have tried processing the changes using sed, but it is not working..
#sed "$ld_lines![LD]!!" "$f"
# Ive also tried using sed as follows:
sed '![LD]!s!music!music/_lossless!' "$f"
# but neither of the above approaches either work or handle both modifications
done解决方案不一定要使用sed,无论最好的是什么。
发布于 2021-10-03 07:41:54
sed '/ \[LD\]/ { s///; s,/,/_lossless/,2; }' file要在包含子字符串[LD]的文件中查找行,可以在sed中使用正则表达式/ \[LD\]/。[需要转义才能失去正则表达式中的特殊含义。我们不需要转义],但为了对称性,我们会转义它。
一旦找到了带有[LD]子字符串的行,就可以用替换s///替换该字符串,即删除它。使用空正则表达式将重复使用最近的表达式,最近的表达式是匹配的[LD]。
下一个替代是用字符串/替换第二个/_lossless/。我们在行的末尾使用2选择正则表达式D12的第二个匹配项,并为命令使用逗号分隔符而不是斜杠。
在创建带有.new文件后缀的文件的循环中:
for name in *.m3u; do
sed '/ \[LD\]/ { s///; s,/,/_lossless/,2; }' -- "$name" >"$name".new
done若要更改macOS上的文件,请使用sed -i '' ...。
for name in *.m3u; do
sed -i '' '/ \[LD\]/ { s///; s,/,/_lossless/,2; }' -- "$name"
done在测试破坏性命令之前请记住备份数据.
发布于 2021-10-03 10:48:31
你可以试试这个sed
for f in *.mp3; do
var1=$(sed -E 's|(.[^/]*)(.[^[]*).*](.*)|\1/_lossless\2\3|' "$f")
mv "$f" "var1"
done输出
/music/_lossless/Miles Davis/1959 - Kind of Blue /Miles Davis - So What.mp3https://unix.stackexchange.com/questions/671610
复制相似问题