Удаление определенной части имени файла (что после второй черты) для всех файлов в папке

Я использую утилиту командной строки 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
7
задан 12 June 2014 в 06:41

5 ответов

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 (переименовывают) команду.

4
ответ дан 12 June 2014 в 06:41

Я использовал бы основанное на Perl rename команда - например, для удаления самой короткой последовательности словесных символов, запускающихся с - перед эти .mp3 суффикс, Вы могли попробовать

rename -nv -- 's/-\w+?[.]mp3$/.mp3/' *.mp3

n, опция выполняет команду в режиме 'пробного прогона' - если соответствия кажутся корректными, удаляют n опция и выполняют ее снова.

11
ответ дан 12 June 2014 в 06:41

Часть, которую Вы не хотите, является видео идентификатором. Можно использовать выходную шаблонную функциональность YouTube-dl:

--output "%(title)s"

это будет использовать только заголовок и опускать идентификатор. Выполненный youtube-dl без параметров для наблюдения других опций.

можно зафиксировать существующие загрузки:

for i in *; do mv "$i" `basename "$i" .mp3 | cut -f -2 -d "-"`.mp3; done

(Это эквивалентно ответу Jakke).

8
ответ дан 12 June 2014 в 06:41

Можно проверить его с этой командой:

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
3
ответ дан 12 June 2014 в 06:41

Решение с помощью только оболочку:

filename=foo-bar-baz

while read -rd-; do
    newname="${newname:+$newname-}$REPLY"
done <<< "$filename"

mv "$filename" "$newname"

Это работает, потому что имя файла не заканчивается тире, таким образом, последний маркер проигнорирован.

0
ответ дан 12 June 2014 в 06:41

Другие вопросы по тегам:

Похожие вопросы: