web-dev-qa-db-fra.com

Créer un script bash pour explorer les sous-répertoires et exécuter une commande avec ffmpeg

actuellement, je lance cette commande ...

# Script designed to convert webm files to m4a for easy listening

for i in *.m4a ; do
    echo ffmpeg -i "\""$PWD/$i"\"" -c:a copy "\""$PWD/${i%.m4a}.mkv"\"" >> ~/bulk.command.txt
done

créer moi-même un fichier de script que je pourrai ultérieurement exécuter pour effectuer un reconditionnement par lots de fichiers multimédias. Malheureusement, ce processus nécessite que je saisisse chaque répertoire devant être reconditionné et que je tape le nom du script.

Parfois, ces projets ont plusieurs répertoires ainsi que des sous-répertoires. De plus, ces projets, lorsqu'ils deviennent gros, exigent que je fasse très attention à la taille du répertoire racine des projets.

J'apprends toujours à coder en bash, et ce script simple m'a pris un certain temps à perfectionner pour m'assurer que presque tous les noms de fichiers possibles sont pris en compte.

Ce que je voudrais faire ensuite est de le modifier de manière à pouvoir simplement aller dans le dossier de musique de mes dossiers de départ, exécuter cette commande une seule fois ET également l’enregistrer dans la disposition des répertoires, mais également placer les fichiers créés par ffmpeg dans un répertoire. répertoire différent. Est-ce que des assistants ont des exemples de code, des termes ou des idées sur la manière dont je peux accomplir cette tâche?

2
Monery

Activer la recherche récurrente dans les sous-répertoires:

shopt -s globstar

Ensuite, vous pourriez faire:

for f in **/*.m4a
do
    printf 'ffmpeg -i %q -c:a copy %q\n' "$PWD/$f" "$PWD/${f%.m4a}.mkv"
done > bulk.command.txt

%q 'printf cite des chaînes de caractères afin qu'elles puissent être utilisées en toute sécurité comme entrée Shell, de sorte que vous n'ayez pas à vous soucier de ces guillemets:

  %q    quote the argument in a way that can be reused as Shell input

Si vous en faites un script, vous pouvez utiliser des arguments pour décider d'utiliser un autre répertoire pour les fichiers de sortie:

#! /bin/bash
shopt -s globstar

for f in **/*.m4a
do
    printf 'ffmpeg -i %q -c:a copy %q\n' "$PWD/$f" "${1:-$PWD}/${f%.m4a}.mkv"
done > bulk.command.txt

${foo:-bar} utilise la valeur de la variable foo, si elle n'est pas vide, ou bar, sinon, le premier argument est utilisé s'il n'est pas vide et $PWD sinon .

Dans ce cas, vous devrez recréer la structure de répertoires, ce qui peut être fait avec mkdir -p:

#! /bin/bash
shopt -s globstar

for f in **/*.m4a
do
    printf 'mkdir -p %q\n' "${1:-$PWD}/${f%/*}"
    printf 'ffmpeg -i %q -c:a copy %q\n' "$PWD/$f" "${1:-$PWD}/${f%.m4a}.mkv"
done > bulk.command.txt

C'est si vous avez vraiment besoin de créer un script pour une utilisation ultérieure. Personnellement, je ne vois pas le problème - vous pouvez exécuter la boucle directement lorsque vous devez réellement l'exécuter:

#! /bin/bash
shopt -s globstar

for f in **/*.m4a
do
    mkdir -p "${1:-$PWD}/${f%/*}"
    ffmpeg -i "$PWD/$f" -c:a copy "${1:-$PWD}/${f%.m4a}.mkv"
done > bulk.command.txt
3
muru