Isso deve ser feito, supondo que nenhum dos seus nomes de arquivo contenha <
:
grep -Po 'file://\K[^<]+' now.xspf | while IFS= read -r file; do
song="${file//%20/ }"
cp "$song" /path/to/target;
done
Explicação
O -o
sinalizador diz grep
para imprimir apenas a parte correspondente de uma linha e o -P
ativa Perl Compatible Regular Expressions que nos fornecem \K
. O \K
faz com que grep
descarte tudo que foi correspondido antes, portanto, o resultado é que file://\K[^<]+
corresponderá à string mais longa de caracteres que não são <
e que vêm após file://
.
Isso é então enviado para um loop while com IFS=
para desativar a divisão de palavras no espaço em branco e -r
para tratar as barras invertidas como caracteres normais.
A linha SONG="${file//%20/ }"
converte todos os %20
em (espaço vazio). Caso contrário, ele retornará um erro de "caminho não encontrado" quando tentar copiar as músicas na última linha.
Se os nomes dos seus arquivos puderem conter <
, use isso:
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
Observação: As duas soluções assumem que nenhum dos seus nomes de arquivo contém novas linhas.