web-dev-qa-db-fra.com

Renommez les fichiers en fonction des dossiers parents et déplacez-vous vers le nouvel emplacement.

J'ai une structure de répertoire comme celle-ci:

./BBC_english/

 2017-09-19.20.00.3-0.rec/00001.mpeg
 2017-09-19.21.00.3-0.rec/00001.mpeg
 2017-09-19.22.00.3-0.rec/00001.mpeg
 2017-09-19.23.00.3-0.rec/00001.mpeg

Et je dois renommer le 00001.mpeg en tant que dossiers parent de ce type pour chaque dossier de ./ J'ai besoin de la date du jour et de l'heure d'enregistrement dans ce format, par exemple - je n'ai pas besoin de 2017 en les nouveaux noms de fichiers

Et à la fin, je dois déplacer tous les fichiers mpeg renommés vers un nouveau chemin comme celui-ci:

./newpath/

BBC_english__09-19__20.00.mpeg   
BBC_english__09-19__21.00.mpeg    
BBC_english__09-19__22.00.mpeg
BBC_english__09-19__23.00.mpeg

Tout d'abord, j'utilise Fedora 20 (je sais que c'est le forum Ubuntu) et lorsque j'exécute la commande mv, elle ne prend pas en charge l'option -v et ne dispose que de ces options:

-f -i -n

Et vous devriez savoir dans le chemin source que mon enregistreur vidéo crée un nouveau fichier toutes les heures.

J'ai donc besoin d'un script récursif pour le faire pour tous les fichiers du dossier source uniquement pour le fichier .mpeg (j'utiliserai le script après que cela ait fonctionné pour moi dans cron), mais aucun des scripts que vous envoyez ici ne fonctionne pour moi maintenant.

1
lockheed

Puisque vous avez mentionné que vous avez Fedora, voici un script Python, qui utilise la syntaxe Python 2, qui devrait fonctionner sans problème ni différence à la fois avec Ubuntu et Fedora. (Ce serait bien d'utiliser prename quels dérivés de Debian sont livrés par défaut, mais malheureusement, Fedora ne le fait pas. Je vais laisser cela comme un exercice pour l'avenir, et prename est toujours utile pour les utilisateurs Ubuntu.)

Voici le script lui-même:

#!/usr/bin/env python

import os
import sys
import shutil

def find_files(start_dir):
    ext_paths = []
    for root,dirs,files in os.walk(start_dir):
        if root == start_dir: continue        
        ext_paths = ext_paths + map( lambda x: os.path.join(root,x),files )
    return ext_paths

def alter_path(path,new_dir):
    newpath = path.replace(".3-0.rec/00001","").replace("2017-","")
    newpath = newpath.replace("BBC_english/","BBC_english__").replace("19.","19__")
    return os.path.join(new_dir,newpath)    

def main():
    for i in find_files(sys.argv[1]):
        print(i,alter_path(i,sys.argv[2]))
        shutil.copy(i,alter_path(i,sys.argv[2]))

if __name__ == '__main__':
    main()

Ici c'est en action:

$ ./rename_mpegs.py  BBC_english/ newpath/                                                                                        
('BBC_english/2017-09-19.23.00.3-0.rec/00001.mpeg', 'newpath/BBC_english__09-19__23.00.mpeg')
('BBC_english/2017-09-19.20.00.3-0.rec/00001.mpeg', 'newpath/BBC_english__09-19__20.00.mpeg')
('BBC_english/2017-09-19.22.00.3-0.rec/00001.mpeg', 'newpath/BBC_english__09-19__22.00.mpeg')
('BBC_english/2017-09-19.21.00.3-0.rec/00001.mpeg', 'newpath/BBC_english__09-19__21.00.mpeg')
$ tree newpath/                                                                                                                   
newpath/
├── BBC_english__09-19__20.00.mpeg
├── BBC_english__09-19__21.00.mpeg
├── BBC_english__09-19__22.00.mpeg
└── BBC_english__09-19__23.00.mpeg

Je vous suggérerais de remplacer la partie shutil.copy() par shutil.move(), ou vous pouvez simplement vous débarrasser de l'ancien répertoire à la fin, mais je vous laisse le soin de décider.

Les règles sont simples: appelez le script avec source en tant qu'argument 1 et destination en tant qu'argument 2 vers le script à partir du répertoire situé au niveau supérieur à BBC_english. Globalement, le script est rapide et sale, le changement de nom est codé en dur; on dirait que ce n'est pas idéal, mais ça marche.

2
Sergiy Kolodyazhnyy

Comme heemayl suggère en réponse à l'article lié, vous pouvez utiliser une série de développements Shell.

En supposant que le répertoire de travail actuel soit le parent de la source et de la destination, vous pouvez utiliser cette boucle sur un système Ubuntu:

_$ for d in ./BBC_english/*; do e="${d##*2017-}"; f="${e%%.[0-9]-[0-9].rec}"; g="${f/./__}"; echo mv -v -- "$d"/* ./newpath/BBC_english__"$g".mpeg; done
mv -v -- ./BBC_english/2017-09-19.20.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__20.00.mpeg
mv -v -- ./BBC_english/2017-09-19.21.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__21.00.mpeg
mv -v -- ./BBC_english/2017-09-19.22.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__22.00.mpeg
mv -v -- ./BBC_english/2017-09-19.23.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__23.00.mpeg
_

Notez que nous parcourons les répertoires plutôt que les fichiers. Cela suppose que vous n’avez en réalité qu’un fichier dans chaque répertoire, ce qui semble être le cas compte tenu de la logique.

Supprimez echo après le test pour déplacer réellement les fichiers. Alors _-v_ force mv à signaler ce qu'il fait.

Si votre mv ne prend pas en charge l'indicateur _-v_ (verbeux) et que vous souhaitez savoir ce qui se passe, vous pouvez utiliser bash pour qu'il soit commenté et vous fournir un résumé détaillé de son utilisation à l'aide de _set -x_

_#!/bin/bash
set -x

for d in ./BBC_english/*; do 
   e="${d##*2017-}"            # remove everything before and including 2017-
   f="${e%%.[0-9]-[0-9].rec}"  # remove the trailing numbers and `.rec`
   g="${f/./__}"               # replace the first `.` with `__`
 echo mv -- "$d"/* ./newpath/BBC_english__"$g".mpeg
 # move to the new path using the edited directory name
done
_

La sortie de ceci après la suppression de echo inclurait le résultat de chaque développement et l'instruction mv pour chaque itération de la boucle. Pour la première itération, la sortie ressemblerait à ceci:

_+ for d in ./BBC_english/*
+ e=09-19.20.00.3-0.rec
+ f=09-19.20.00
+ g=09-19__20.00
+ mv -- ./BBC_english/2017-09-19.20.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__20.00.mpeg
_
2
Zanna

Ce script devrait aider:

#!/bin/bash  

for i in ./BBC_english/*; do
        # Get the path to the file
        path=$(dirname "$(readlink -f "$i")")         

        # get the names for file rename
        f2=$( echo "$path" | grep -Eo "\-[0-9]{2}-[0-9]{2}" | grep -Eo "[0-9]{2}-[0-9]{2}")            
        f1=$( echo "$path" | grep -Eo BBC_english )           
        f3=$(echo "$path" | grep -Eo "\.[0-9]{2}\.[0-9]{2}" | grep -Eo "[0-9]{2}\.[0-9]{2}")                       
        # Rename the files           
        mv -n "$i" ./newpath/"$f1"__"$f2"__"$f3".mpeg

done
0
George Udosen