J'ai récemment converti tous mes fichiers FLAC en un taux d'échantillonnage inférieur de 44,1 kHz et une profondeur de 24 bits (car l'iPhone / iPod ne prend en charge rien de plus) en utilisant XLD sur mon Mac OS 10.7 (Lion).
Bien que j'aie dit à XLD d'écraser tous les fichiers précédents, XLD a ajouté un (1)
à la fin du fichier comme
some_song.m4a
à
some_song(1).m4a
Alors maintenant, je veux supprimer cela (1)
de tous les fichiers FLAC que j'ai convertis.
Je sais que j'aurais probablement pu utiliser un programme ou même un AppleScript pour renommer les fichiers, mais je voulais apprendre à utiliser l'ancienne méthode de ligne de commande.
Je sais que find . -name *\(1\).m4a
va récupérer tout le fichier FLAC converti.
Ensuite, je sais que je dois faire quelque chose avec -exec
et mv
renommer tous les fichiers trouvés. Mais ce que je ne peux pas comprendre, c'est comment conserver le nom de fichier d'origine et supprimer uniquement le (1)
.
Peut-être que je dois faire une capture regex de groupe pour stocker la partie du nom de fichier que je ne veux pas modifier? Ou peut-être qu'il n'est pas possible de tout faire sur une seule ligne et que je devrais créer un script shell (ce que je ne suis pas si à l'aise de faire, mais je suis prêt à l'essayer).
Tous les conseils ou suggestions sont les bienvenus! Merci!
find
) mais qui peut résoudre votre problème réel (conversion de fichiers audio), vous pouvez être intéressé par jeter un œil à audiotools.sourceforge.net et à cet exemple de cas (pour macosx lion) invibe.net/ LaurentPerrinet / SciBlog / 2012-04-22Réponses:
N'essayez pas d'analyser la
find
sortie, sauf en dernier recours. Il est important de réaliser que sur les systèmes de fichiers Unix, les noms de fichiers ne sont pas des chaînes (une idée fausse courante) mais plutôt des blobs binaires qui peuvent contenir n'importe quel caractère sauf/
et le caractère nul. Analyser correctement et en toute sécurité les noms de fichiers est assez pénible que 99% du temps, vous voudrez simplement éviter de le faire complètement (regardez simplement à quel point l'sed
expression dans @ yarek est poilue et même cela ne couvre pas tous les cas) . Heureusement, dans ce cas, il existe une approche beaucoup plus simple:la source
done
?sed
approche des tuyaux est que c'est beaucoup plus sûr. Il est toujours plus facile à lire que la soupe anti-slash regex, à condition que vous compreniez quelques constructions de script shell de base.$arg
variable le rend beaucoup plus facile à lire.find
invoquésh
avec une syntaxe POSIX assez portable. Pour plus de détails, vous pouvez consulter la section sur l'expansion des paramètres , la section sur les commandes composées qui explique lafor
boucle et la spécification POSIXfind
. En plus de ces ressources, je serais heureux de répondre à toutes vos questions spécifiques .Sur Debian et Ubuntu, je peux utiliser
rename 's/\(1\)//' *.m4a
pour résoudre votre problème.la source
man rename
, mais je n'ai pasrename
:-bash: rename: command not found
(which rename
ne montre rien).man -a rename
trouve ici rename (2) - l'appel système et rename (n) - la commande TCL. Il n'y a ni rename (1) ni l'utilitaire lui-même.rename
est un script perl inclus avec les exemples inclus dans certaines installations de perl, et quelques distributions l'incluent dans le chemin car c'est une commande pratique. (@Hobbes peut-être que vous pouvez le trouver sur Internet)rename
est un binaire normal (pas perl). Cependant, une autre mise en garde est que toutes les versions desrename
expressions régulières ne sont pas prises en charge. La version que j'ai par exemple ne vous permet que de remplacer directement les chaînes, par exemplerename '(1)' '' *.m4a
rename
script Perl n'est installé que par Debian et ses dérivés. D'autres systèmes Linux ont unrename
utilitaire différent (montré par Patrick). OSX n'a ni l'un ni l'autre.Dans zsh, en utilisant zmv :
Dans le deuxième argument (le nouveau nom),
$1
et$2
faites référence aux groupes entre parenthèses(PATTERN)
dans le modèle source. Une autre façon d'écrire ce changement de nom estla source
L'approche suivante vous donne la possibilité de prévisualiser / élaguer les commandes générées avant de les exécuter, et elle est très portable: elle devrait fonctionner non seulement sur un mac, pas seulement avec bash, et pas seulement avec GNU sed; même sur les systèmes sans
find
commande (1), il est possible de le remplacer pardu
(1) sans problème.Si vous êtes satisfait des commandes imprimées, réexécutez avec en
| sh -x
annexe.Si vous vous souciez des espaces dans les noms de fichiers, ajoutez un autre s pour échapper à tous les espaces:
Si d'autres caractères spéciaux sont attendus, cela devient un peu plus délicat:
La première fonction convertit tout
'
en une forme telle que celles-ci sont prises littéralement lorsqu'elles se trouvent au milieu d''...'
une chaîne échappée. La deuxième fonction génère des commandes mv dont les arguments sont inclus à l'intérieur'...'
.la source
(
et tous les autres caractères spéciaux) ou n'ajoute pas de guillemets autour du nom de fichier. J'ai essayé de modifier votre commande, mais je n'ai pas pu comprendre comment ajouter des guillemets autour des deux noms de fichiers pour lamv
commande. L'une des sorties résultantes de votre commande estmv ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us(1).m4a ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us.m4a
. Et si j'exécute cette commande, j'obtiens-bash: syntax error near unexpected token '('
.e
commande après substitution. Par exemplefind . -name '*(1).m4a' | sed 's/\(.*\)(1).m4a$/mv & \1.m4a/e'
, la commande sera exécutée sans canalisation verssh -x
.Voici un petit script qui le fait:
la source
`find ...`