web-dev-qa-db-fra.com

Suppression d'une partie spécifique du nom de fichier (après le deuxième tiret) pour tous les fichiers d'un dossier

J'utilise l'utilitaire de ligne de commande youtube-dl pour télécharger des vidéos à partir de YouTube et créer des fichiers MP3 à partir de avconv. Je le fais sous Ubuntu 14.04 et j'en suis très heureux.

L'utilitaire télécharge les fichiers et les enregistre avec le schéma de nom suivant:

TITLE(artist-track)-ID.mp3

Donc, un nom de fichier réel ressemble à:

EPIC RAP BATTLE of MANLINESS-_EzDRpkfaO4.mp3

Certains autres noms de fichier dans le dossier ressemblent à:

EPIC RAP BATTLE of MANLINESS-_EzDRpkfaO4.mp3
Martin Garrix - Animals (Official Video)-gCYcHz2k5x0.mp3
Stromae - Papaoutai-oiKj0Z_Xnjc.mp3

Au début, ce n'était pas un problème. Cela ne me dérangeait pas lorsque j'écoutais ma musique dans Rhytmbox. Mais lorsque vous passez à un téléphone ou à un autre appareil, il est assez déroutant de voir un nom aussi long, et certains lecteurs, comme ceux de Samsung, considèrent cette dernière partie (id après le second tiret) comme un album ou quelque chose du genre.

J'aimerais créer un script bash qui supprime ce qui se trouve après le deuxième tiret dans le nom de tous les fichiers, afin que cela les rende ainsi:

De: Martin Garrix - Animals (Official Video)-gCYcHz2k5x0.mp3

À: Martin Garrix - Animals (Official Video).mp3

Est-il également possible de demander à youtube-dl d'exclure l'ID à partir de maintenant?

Je télécharge actuellement avec la commande:

youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 URL
6
Bodo

sed peut accomplir cela en une seule ligne, bien que de manière plutôt compliquée.

ls | sed 's/\(.*\)\(-.*\)/mv \"&\" \"\1.mp3\"/' | bash

Cette liste répertorie d'abord les fichiers du répertoire en cours (en supposant que tous les fichiers que vous souhaitez renommer se trouvent dans le répertoire en cours), puis utilise la commande s/regex/replacement de sed pour générer une commande sensible mv qui est ensuite dirigée vers bash qui l'exécute. . Cela suppose que tous vos fichiers ont la forme "A-C.mp3" ou "A - B-C.mp3". Voici comment cela fonctionne:

La partie regex de la commande sed est

\(.*\)\(-.*\)

cela "groupe" le nom en deux groupes (délimités par des parenthèses): un ". *" correspondant (tout nombre de caractère) et un autre "-. *", un tiret suivi d'un nombre quelconque de caractère. Notez que cela correspond au nom de fichier entier (en deux groupes). Notez également que, puisque l'expression rationnelle "gourmande" est utilisée, le premier groupe correspondra à "A" dans "A-C.mp3" et "A - B", et pas seulement "A", dans "A - B-C.mp3", comme souhaité.

La partie de remplacement de la commande sed est

mv \"&\" \"\1.mp3\"/

Notez qu'un caractère & indique à sed d'insérer l'intégralité du modèle correspondant à l'expression régulière, en l'occurrence le nom de fichier complet, et le\1 lui demande d'insérer la partie du nom de fichier correspondant au premier groupe ". *". Ces deux sont combinés avec un mv précédent et un .mp3 suivant, avec des guillemets échappés pour produire une commande de renommage sensible. Par exemple, pour "A - B-C.mp3", la commande sed complète produira:

mv "A - B-C.mp3" "A - B.mp3"

Et finalement, tout cela est dirigé vers bash, qui exécute avec bonheur la commande mv (renommer).

3
icasdri

J'utiliserais la commande rename basée sur Perl - par exemple, pour supprimer la séquence la plus courte de caractères Word commençant par - avant le suffixe .mp3, vous pouvez essayer

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

L'option n exécute la commande en mode 'exécution à sec' - si les correspondances semblent correctes, supprimez l'option n et exécutez-la à nouveau.

11
steeldriver

La partie que vous ne voulez pas, c'est l'identifiant vidéo. Vous pouvez utiliser la fonctionnalité de modèle de sortie de youtube-dl:

--output "%(title)s"

cela utilisera uniquement le titre et omettra l'id. Exécutez youtube-dl sans paramètre pour voir les autres options.

Vous pouvez corriger vos téléchargements existants:

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

(Ceci est équivalent à la réponse de Jakke).

8
roadmr

Vous pouvez le vérifier avec cette commande:

for i in *.mp3; do echo "$(echo $i|cut -d- -f1,2).mp3"; done

Notez que vous avez des noms de fichiers sans 2 tirets, donc cela ne fonctionnera pas pour tout.

Si vous voulez réellement changer les noms,

for i in *.mp3
do
  newname="$(echo $i|cut -d- -f1,2).mp3";
  mv $i $newname
done
3
Jakke

Une solution utilisant uniquement le shell:

filename=foo-bar-baz

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

mv "$filename" "$newname"

Cela fonctionne car le nom du fichier ne se termine pas par un tiret, le dernier jeton est donc ignoré.

0
nyuszika7h