我有一个 VLC 播放列表 (.xspf),其中包含 100 多首歌曲,分散在我的计算机各处。我正在寻找一种方法来将此播放列表及其所有歌曲保存到另一个文件夹 - 闪存驱动器、外部驱动器或只是计算机中的其他位置。我该怎么做?
编辑
xspf 播放列表采用 XML 格式,格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<playlist xmlns="http://xspf.org/ns/0/" xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/" version="1">
<title>Playlist</title>
<trackList>
<track>
<location>file:///home/subroot/Music/3%20Days%20Grace%20-%20Wake%20Up.mp3</location>
<title>Wake Up</title>
<creator>3 Days Grace</creator>
<album>Three Days Grace</album>
<trackNum>10</trackNum>
<annotation> </annotation>
<duration>206036</duration>
<extension application="http://www.videolan.org/vlc/playlist/0">
<vlc:id>0</vlc:id>
</extension>
</track>
.
. [Many more tracks here]
.
</trackList>
<extension application="http://www.videolan.org/vlc/playlist/0">
<vlc:item tid="0"/>
.
. [Other id's here]
.
</extension>
</playlist>
答案1
假设您的文件名都不包含以下内容<
,这样就可以了:
grep -Po 'file://\K[^<]+' now.xspf | while IFS= read -r file; do
song="${file//%20/ }"
cp "$song" /path/to/target;
done
解释
标志-o
指示grep
仅打印匹配的行部分,并且-P
激活 Perl 兼容正则表达式,这为我们提供了\K
。\K
导致grep
丢弃在它之前匹配的所有内容,因此结果是将匹配在它之后的file://\K[^<]+
最长的非字符字符串。<
file://
然后将其输入到 while 循环中,以IFS=
关闭空格处的单词拆分,-r
并将反斜杠视为普通字符。
该行将SONG="${file//%20/ }"
所有内容转换%20
为(空白处)。否则,当它尝试复制最后一行中的歌曲时,它会返回“未找到路径”错误。
如果您的文件名可以包含<
,请改用以下内容:
perl -lne '@foo=(m#file://(.+?)</location>#g); END{print $_ for @foo}' playlist.xspf |
while IFS= read -r file; do
cp "$file" /path/to/target/;
done
笔记:这两种解决方案都假定您的文件名都不包含换行符。