2015-08-03 3 views
0

Je suis sous OS X 10.8.5 donc la commande rename n'est pas une option et ce que j'ai codé correspond à ce que fait le reste du script bash donc je préfère rester dans ce cadre mais modifiez-le un peu, si possible. J'utilise cependant une version plus récente de bash puis le défaut d'expédition OS X 10.8.5, j'utilise GNU bash 4.3.30 que j'ai installé à partir du code source. (Oui, je sais que je suis quelques taches derrière.)Existe-t-il une méthode purement bash pour éliminer certaines commandes externes dans mon cas d'utilisation?

Ce que je voudrais faire dans la fonction ci-dessous, si possible, est de remplacer la commande de mvcible qui est l'argument en utilisant commande substitution avec quelque chose de totalement dans pur bas. Plus précisément, je voudrais éliminer l'utilisation de tuyaux et exécutables externes.

Question: la substitution de commande Can J'utilise soit être modifié ou remplacé par extension de nom de fichier et ou motif correspondant à ne pas utiliser tuyaux ou executables externes pour atteindre mon objectif déclaré? (ou autre chose plus raisonnable.)

  • J'ai lu les trois sections connexes dans le Manuel de référence Bash mais je dois admettre que je ne voyais pas comment il pourrait facilement être possible. Bien que j'ai essayé de le recoder quelques fois, mais la sortie n'était pas du tout ce que je voulais, c'était soit noms de fichiers ou l'erreur ... bad substitution.

  • Tous les cibles noms de fichiers dans le répertoire de travail se soit déjà correspondre RegEx.$ext ou sera RegEx+foobar.$ext et la façon dont je l'ai codé la fonction et en utilisant mv est si elle est correspondant pas déjà le RegEx renomme la cible noms de fichiers de RegEx+foobar.$ext à RegEx.$ext. Tous les noms de fichiers quand tronqués seront unique, donc il n'y a pas besoin de se soucier d'écraser un RegEx.$ext existant nom et par conséquent aucune erreur supplémentaire vérification nécessaire.

Exemple Les noms de fichiers: filenameC01P01.png filenameC01P02foobar.jpg filenameC01P03.TIF

Résultats escomptés:filenameC01P02foobar.jpg ->filenameC01P02.jpg

code:

function truncate_filenames() { 
    for f in *.png *.jpg *.tif; do 
     if [[ -f $f ]]; then 
      ext="${f:(-3)}" 
      if [[ ! ${f%.*} =~ .*C[0-9]{2}P[0-9]{2}$ ]]; then 
       mv -v "$f" "$(echo "$f" | grep -Eo '.*C[0-9]{2}P[0-9]{2}').$ext" 
      fi 
     fi 
    done 
} 

Répondre

3

Il semble que vous voulez juste enlever quoi que ce soit suivant le modèle CxxPxx, mais conserver l'extension.

# Capture both the good part and the trailing garbage 
[[ ${f%.*} =~ (.*C[0-9]{2}P[0-9]{2})(.*)$ ]] 
if [[ -n ${BASH_REMATCH[2]} ]]; then 
    mv -v "$f" "${BASH_REMATCH[1]}.$ext" 
fi 

Vous pouvez probablement capturer l'extension dans l'expression régulière et, ce qui élimine la nécessité de l'extraire séparément.

[[ $f =~ (.*C[0-9]{2}P[0-9]{2})(.*)\.(.*)$ ]] 
if [[ -n ${BASH_REMATCH[2]} ]]; then 
    mv -v "$f" "${BASH_REMATCH[1]}.${BASH_REMATCH[3]}" 
fi 
+0

On dirait que je vais devoir lire sur BASH_REMATCH. Quels autres mécanismes (en l'absence de terme approprié) sont utilisés dans votre code afin que je puisse lire dans le manuel pour comprendre et ensuite mettre en œuvre ce que votre code est en train de faire. En d'autres termes les parenthèses dans '(. * C [0-9] {2} P [0-9] {2}) (. *) $' Son utilisation dans ce cas s'appelle quoi? Est-ce couvert par BASH_REMATCH dans le manuel? Aussi dans le deuxième exemple 'foobar' après le' RegEx' peut contenir des points, par ex. 'filenameC01P02foo.bar.jpg', cela change donc ce' '[[$ f = ~ (. * C [0-9] {2} P [0-9] {2}) (. *) \. (. *) $]] 'est en train de faire? En d'autres termes, la portion '(. *) $' Est-elle gourmande? – user3439894

+0

Les parenthèses forment simplement des groupes de capture, dont le contenu est stocké dans 'BASH_REMATCH', donc lire à ce sujet devrait suffire. '. *' est gourmand, donc celui précédant le littéral '.' devrait consommer autant qu'il le peut, ne laissant qu'une seule extension pour l'instance finale. – chepner

+0

J'ai testé les deux permutations et bien sûr chaque travail comme prévu. Même si je ne comprends pas encore tout à fait ce qu'il fait, je suis plutôt à l'aise dans la mise en œuvre du code que vous avez fourni. Je vais lire un peu plus dans le Manuel de référence Bash et d'autres sources pour mieux comprendre. Je vous remercie! – user3439894