Renommer les fichiers faire le nom du dossier de l'arborescence dans terminal, shell mac ou shell linux


1

Je travaille avec une arborescence de dossiers et de fichiers avec la structure

  • \ Stories \ 00 \ 0 \ 00000 \ temp.xxx
  • \ Stories \ 00 \ 0 \ 00001 \ temp.xxx
  • ...
  • \ Histoire \ 10 \ 5 \ 10552 \ temp.xxx
  • \ Histoire \ 10 \ 5 \ 10553 \ temp.xxx
  • ...
  • \ Histoire \ 45 \ 9 \ 45998 \ temp.xxx
  • \ Histoire \ 45 \ 9 \ 45999 \ temp.xxx

Ce dont j'ai besoin, c'est de renommer les fichiers de sorte que temp.xxx soit transformé en un nom de fichier séquencé, comme indiqué ci-dessous:

  • \ Stories \ 00 \ 0 \ 00000 \ 00000.xxx
  • \ Histoires \ 00 \ 0 \ 00001 \ 00001.xxx
  • ...
  • \ Histoire \ 10 \ 5 \ 10552 \ 10552.xxx
  • \ Histoire \ 10 \ 5 \ 10553 \ 10553.xxx
  • ...
  • \ Histoire \ 45 \ 9 \ 45998 \ 45998.xxx
  • \ Histoire \ 45 \ 9 \ 45999 \ 45999.xxx


merci prasanna, mais ce que je cherche, c'est une ligne de commande dans un shell capable de le faire sans interactions avec l'interface graphique.
Alejandro O'Byrne

Réponses:


0

Si votre structure est uniforme et que vous avez la profondeur de 3 à l'intérieur de votre dossier History, la manière intuitive serait peut-être d'avoir des boucles imbriquées puis d'utiliser le mv pour renommer.

Le code suivant suppose que vous avez un fichier dans chaque dossier de la couche 3 et que / History ne contient rien d'autre que des répertoires.

for layer1 in /History/*; do
    for layer2 in /History/$layer1/*; do
        for layer3 in /History/$layer1/$layer2/*; do
           for files in /History/$layer1/$layer2/$layer3/*; do
                mv files $layer3.xxx
            done
        done
    done
done

peut-être que ces deux liens sont également utiles:

http://www.cyberciti.biz/faq/bash-for-loop/

https://stackoverflow.com/questions/539583/how-do-i-recursively-list-all-directories-at-a-location-breadth-first


Vous voudrez peut-être citer vos variables.
slhck

0

Vous pouvez le faire avec une commande comme celle-ci:

find . -name "temp*" | sed -E 's|(.*)\/(.*)\/temp(.[a-z]{3})|mv & \1\/\2\/\2\3|g' | source /dev/stdin

Explication pas à pas.

Ceci est votre exemple d'entrée:

$ find . -name "temp*"
./History/10/5/10552/temp.xxx
./History/10/5/10553/temp.xxx
./Stories/00/0/00000/temp.xxx
./Stories/00/0/00001/temp.xxx

Je modifie la sortie pour l'adapter à la sortie requise.

$ find . -name "temp*" | sed -E 's|(.*)\/(.*)\/temp(.[a-z]{3})|\1\/\2\/\2\3|g'
./History/10/5/10552/10552.xxx
./History/10/5/10553/10553.xxx
./Stories/00/0/00000/00000.xxx
./Stories/00/0/00001/00001.xxx

Donc, nous transformons chaque temp* dans une mv commande avec les noms de sortie requis. La commande ressemble à ceci:

$ find . -name "temp*" | sed -E 's|(.*)\/(.*)\/temp(.[a-z]{3})|mv & \1\/\2\/\2\3|g'
mv ./History/10/5/10552/temp.xxx ./History/10/5/10552/10552.xxx
mv ./History/10/5/10553/temp.xxx ./History/10/5/10553/10553.xxx
mv ./Stories/00/0/00000/temp.xxx ./Stories/00/0/00000/00000.xxx
mv ./Stories/00/0/00001/temp.xxx ./Stories/00/0/00001/00001.xxx

Pour exécuter chaque commande de la sortie précédente, il faut ajouter | source /dev/stdin à la fin de la commande.

Les résultats seront les suivants:

$ find . -name "*.xxx"
./History/10/5/10552/10552.xxx
./History/10/5/10553/10553.xxx
./Stories/00/0/00000/00000.xxx
./Stories/00/0/00001/00001.xxx
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.