web-dev-qa-db-ja.com

VLC xspfプレイリスト内のすべての音楽ファイルを別のフォルダーに保存する

コンピューター全体に散らばる100曲以上のVLCプレイリスト(.xspf)があります。このプレイリストとすべての曲を別のフォルダー(フラッシュドライブ、外部ドライブ、またはコンピューターの別の場所)に保存する方法を探しています。これどうやってするの?

編集

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>
3
Parto

これは、ファイル名に<が含まれていないことを前提にしています。

grep -Po 'file://\K[^<]+' now.xspf | while IFS= read -r file; do
    song="${file//%20/ }"
    cp "$song" /path/to/target;
done

説明

-oフラグは、行の一致した部分のみを印刷するようgrepに指示し、-P\Kを与えるPerl互換正規表現をアクティブにします。 \Kによりgrepがその前に一致したものをすべて破棄するため、file://\K[^<]+<の後に続くfile://以外の文字の最長文字列に一致します。

これは、IFS=を使用してwhileループに送られ、空白でのWord分割をオフにし、-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

注:両方のソリューションは、ファイル名に改行が含まれていないことを前提としています。

2
terdon