Попытка отформатировать имена музыкальных файлов - PullRequest
2 голосов
/ 15 января 2012

tl; dr. Как переименовать файл / foo / bar в / foo / bar-foo для множества различных файлов в разных папках?

Сейчас музыка моей мамы записана на 32-ГБ перьевом диске.что она подключена к своей машине.На перьевом диске есть папки с названиями артистов, внутри этих папок есть папки с названиями альбомов, а внутри - сами песни.Когда моя мама играет музыку в своей машине, машина будет воспроизводить музыку только из одной папки за раз.Она бы предпочла случайную игру всех песен.Мое решение состояло в том, чтобы сделать

cp ./*/*/*/* /otherfolderonmycomputer

, чтобы собрать все файлы песен в одну папку, затем удалить все данные на перьевом диске и скопировать эту папку обратно в нее.Однако была одна проблема.У нее разные версии каждой песни в разных альбомах.Эти песни имеют одинаковые заголовки, и команда cp хочет перезаписать одну или другую.Решение, которое я придумал, состояло в том, чтобы переименовать каждый из музыкальных файлов в SongTitle-AlbumName, чтобы cp не захотел перезаписывать что-либо, и чтобы она могла сказать, какую версию каждой песни она слушает.Как бы я это сделал?

Ответы [ 4 ]

2 голосов
/ 15 января 2012

Конечно, это может быть сценарий (вариант # 1), для которого есть бесконечные возможности;и «awk» - один из многих вариантов (замените жестко закодированный «foo / bar / ...» на (например) find * -name \*.mp3):

$ for x in foo/bar/{abc,xyz}/{f1,f2,f3}.mp3
do
  newfile=$( echo $x | awk -F/  '{ print $3 "-" $2 "-" $NF }')
  echo mv $x foo/$newfile
done

mv foo/bar/abc/f1.mp3 foo/abc-bar-f1.mp3
mv foo/bar/abc/f2.mp3 foo/abc-bar-f2.mp3
mv foo/bar/abc/f3.mp3 foo/abc-bar-f3.mp3
mv foo/bar/xyz/f1.mp3 foo/xyz-bar-f1.mp3
mv foo/bar/xyz/f2.mp3 foo/xyz-bar-f2.mp3
mv foo/bar/xyz/f3.mp3 foo/xyz-bar-f3.mp3

Но, возможно, более приятный, простой, более гибкий (опция # 2) будет использовать pytagsfs , которая создает виртуальную (плавкую) файловую систему на основе определенных вами правил, что делает вашу структуру каталогов "видимой" так, как вы этого хотите.Как только вы это сделаете, скопируйте эту структуру виртуального каталога в структуру физического каталога.Таким образом, вы можете настроить виртуальный макет, просмотреть его, а затем просто скопировать, так сказать, на флешку «сделай так».(Однако для этого вам может понадобиться довольно просторное рабочее пространство.)

$ tree foo-orig  # or ls -R, whatever
... your files...
$ mkdir by-genre
$ pytagsfs -o format='/%g/%a - %t.%e' foo-orig by-genre
$ tree by-genre
... in different dir structure
$ cp -r by-genre foo-new  # make it so
1 голос
/ 15 января 2012

В одну сторону, используя perl:

Содержимое script.pl:

use warnings;
use strict;
use File::Find;
use File::Copy;

## Accept one dir with files as input argument.
die qq[Usage: perl $0 <dir>\n] unless @ARGV == 1;

my $arg_dir = $ARGV[0];

find( \&wanted, $arg_dir );

sub wanted {

    ## Return if file is special.
    return unless -f; 

    ## Get last dir of current path.
    my ($album) = $File::Find::dir =~ m|/([^/]+)$|;

    ## Get extension of the file (supposed mp3 if music).
    my ($extension) = ($File::Find::name =~ m|.*\.([^.]+)$|);

    ## Remove the extension, because I will add the album name just before it.
    s/\.[^.]+$//;

    ## Rename each file into base dir passed as argument to the script.
    #rename( $File::Find::name, $arg_dir . qq[/] . $_ . qq[-] . $album . qq[.] . $extension ) || die;
    copy( $File::Find::name, $arg_dir . qq[/] . $_ . qq[-] . $album . qq[.] . $extension ) || die;
}

Запустите сценарий: передайте в качестве аргумента базовый путь всех музыкальных файлов, и сценарий будет выполнять поиск по поддереву каталога, просматривая каждый перемещаемый файл и переименовывая его в базовый путь:

perl script.pl ~/temp/music/

Примите во внимание последние две инструкции скрипта, у меня есть copy(...) без комментариев, и он будет переименовывать новые файлы без удаления старых. Если вы уверены, что это работает, прокомментируйте эту строку и раскомментируйте предыдущую rename(...). Они похожи, но копирование явно более безопасное.

1 голос
/ 15 января 2012

Ну, немного неортодоксально, но вы можете попробовать что-то вроде этого -

while IFS='$\n' read line ; do 
     mv $line $line$(sed 's#/#-#g' <<< $(dirname ${line#.})); 
done < <(find . -type f -name "*.mp3")

Тест:

До:

[jaypal:~/Temp] find . -type f -name "*.mp3"
./c/c1/c.mp3
./c/c2/cc.mp3

После запуска скрипта:

[jaypal:~/Temp] find . -type f -name "*.mp3*"
./c/c1/c.mp3-c-c1
./c/c2/cc.mp3-c-c2
1 голос
/ 15 января 2012

Как переименовать файл / foo / bar в / foo / bar-foo?

mv /foo/bar /foo/bar-foo

чтобы сделать это с несколькими файлами / папками рекурсивно, используя имя папки, смотрите здесь: http://www.linuxquestions.org/questions/linux-general-1/how-to-recursively-rename-files-using-their-directory-name-pattern-367807/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...