Я использую утилиту командной строки youtube-dl
для загрузки видео с YouTube и создания mp3-файлов из них с помощью avconv
. Я делаю это под Ubuntu 14.04 и очень доволен этим.
Утилита загружает файлы и сохраняет их по следующей схеме имен:
TITLE(artist-track)-ID.mp3
Таким образом, фактическое имя файла выглядит следующим образом:
EPIC RAP BATTLE of MANLINESS-_EzDRpkfaO4.mp3
Некоторые другие имена файлов в папка выглядит так:
EPIC RAP BATTLE of MANLINESS-_EzDRpkfaO4.mp3
Martin Garrix - Animals (Official Video)-gCYcHz2k5x0.mp3
Stromae - Papaoutai-oiKj0Z_Xnjc.mp3
Сначала это не было проблемой. Меня это не беспокоило, когда я слушал музыку в Ритмбоксе. Но при переходе на телефон или другие устройства довольно сложно увидеть такое длинное имя, и некоторые плееры, например, Samsung, рассматривают эту последнюю часть (идентификатор после второго тире) имени как альбом или что-то в этом роде.
Я хотел бы создать сценарий bash, который удаляет то, что после второй тире в имени для всех файлов, поэтому он будет выглядеть следующим образом:
От: Martin Garrix - Animals (Official Video)-gCYcHz2k5x0.mp3
Кому: Martin Garrix - Animals (Official Video).mp3
Можно ли также поручить youtube-dl
исключать идентификатор с этого момента?
Я сейчас загружаю с помощью команды:
youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 URL
sed может выполнить это в одной строке, хотя довольно замысловатым способом.
ls | sed 's/\(.*\)\(-.*\)/mv \"&\" \"\1.mp3\"/' | bash
Это сначала перечисляет файлы в текущем каталоге (принимающий все файлы, которые Вы хотите переименовать, находятся в текущем каталоге), и затем использует команду s/regex/replacement sed для генерации разумной команды mv, которая затем передается по каналу для избиения, который выполняет его. Это предполагает, что все Ваши файлы являются чем-то вроде формы "A-C.mp3" или "-B-C.mp3". Вот то, как это работает:
regex часть команды sed
\(.*\)\(-.*\)
, это "группирует" имя в две группировки (разграниченный с завершенными круглыми скобками): одно соответствие ".*" (любое количество любого символа) и другое соответствие "-.*", тире, сопровождаемый любым количеством любого символа. Заметьте, что это соответствует всему имени файла (в двух группах). Также обратите внимание, что, так как "жадный" regex используется, первая группа будет соответствовать "A" в "A-C.mp3" и "-B", не только "A", в "-B-C.mp3", как требуется.
сменная деталь команды sed
mv \"&\" \"\1.mp3\"/
Примечание что & символ дает sed команду вставлять весь шаблон, который соответствовал regex, в этом случае который является всем именем файла, и эти \1 дают sed команду вставлять часть имени файла, которое соответствовало первой группировке ".*". Эти два объединены с предыдущим mv и запаздыванием .mp3, с завершенными кавычками для создания разумного переименовывают команду. Например, для "-B-C.mp3", полная команда sed произведет:
mv "A - B-C.mp3" "A - B.mp3"
И наконец все это передается по каналу для избиения, который счастливо выполняется, mv (переименовывают) команду.
Я использовал бы основанное на Perl rename
команда - например, для удаления самой короткой последовательности словесных символов, запускающихся с -
перед эти .mp3
суффикс, Вы могли попробовать
rename -nv -- 's/-\w+?[.]mp3$/.mp3/' *.mp3
n
, опция выполняет команду в режиме 'пробного прогона' - если соответствия кажутся корректными, удаляют n
опция и выполняют ее снова.
Часть, которую Вы не хотите, является видео идентификатором. Можно использовать выходную шаблонную функциональность YouTube-dl:
--output "%(title)s"
это будет использовать только заголовок и опускать идентификатор. Выполненный youtube-dl
без параметров для наблюдения других опций.
можно зафиксировать существующие загрузки:
for i in *; do mv "$i" `basename "$i" .mp3 | cut -f -2 -d "-"`.mp3; done
(Это эквивалентно ответу Jakke).
Можно проверить его с этой командой:
for i in *.mp3; do echo "$(echo $i|cut -d- -f1,2).mp3"; done
Примечание, что у Вас действительно есть имена файлов без 2 тире, таким образом, оно не будет работать на все.
, Если Вы на самом деле хотите изменить имена,
for i in *.mp3
do
newname="$(echo $i|cut -d- -f1,2).mp3";
mv $i $newname
done
Решение с помощью только оболочку:
filename=foo-bar-baz
while read -rd-; do
newname="${newname:+$newname-}$REPLY"
done <<< "$filename"
mv "$filename" "$newname"
Это работает, потому что имя файла не заканчивается тире, таким образом, последний маркер проигнорирован.