batch renommer les fichiers zip en fonction des noms de fichiers contenus

2

J'ai un répertoire avec 15000 fichiers zip. Je voudrais renommer tous les fichiers qui, une fois décompressés, contiennent un fichier de la forme

YYYYMMDD_IPC.csv

YYYYMMDD se trouve être une date mais pour les besoins de ce problème est une chaîne de 8 chiffres exactement. Ensuite, le fichier zip lui-même doit être renommé en

YYYYMMDD_IPC.zip.

Je suis arrivé jusqu'à la ligne de commande suivante mais je ne sais pas comment capturer le YYYYMMDD du fichier contenu à utiliser pour renommer les fichiers zip:

find . -iname '*.zip' | while read file; do unzip -l "$file" | grep -q -P '\d{8}_IPC.csv' && echo $file; done 2>&- 

Merci d'avoir lu.

    
posée user2926302 25.09.2015 - 01:17
la source

1 réponse

4
find . -iname '*.zip' -exec bash -c 'name=$(unzip -qql ""  '*_IPC.csv' | grep -oE '[[:digit:]]{8}_IPC.csv' | head -n1); [ "$name" ] && mv "" "${name%csv}zip"' none {} ';'

Comment ça marche

Cette commande a la forme suivante:

find . -iname '*.zip' -exec bash -c '...' none {} ';'

Ceci recherche le fichier .zip dans le répertoire en cours et tous les sous-répertoires sous celui-ci. Pour chaque fichier trouvé, la commande bash en guillemets simples est exécutée. Le nom du fichier trouvé est fourni à l'argument un, , à la commande bash. Dans notre cas, la commande bash comporte deux parties. Le premier extrait le nom du fichier csv et l’enregistre dans la variable bash name :

name=$(unzip -qql ""  '*_IPC.csv' | grep -oE '[[:digit:]]{8}_IPC.csv' | head -n1)

Ce qui précède utilise la substitution de commande : la commande dans $(...) est exécutée et sa sortie standard est capturée. Dans ce cas, nous l’affectons à la variable name . La commande unzip -qql "" '*_IPC.csv' extrait silencieusement tous les noms de fichiers du fichier zip correspondant au glob *_IPC.csv . Nous n'avons pas besoin de nous limiter au glob *_IPC.csv , mais si le fichier zip contient de nombreux fichiers, cela peut accélérer les choses.

La commande grep, rep -oE '[[:digit:]]{8}_IPC.csv' , sélectionne en outre uniquement les noms commençant par 8 chiffres. La commande head -n1 sélectionne le premier nom trouvé. S'il n'y en avait qu'un seul, head -n1 ne serait pas nécessaire. Mais conserver head pourrait accélérer les choses car cela entraîne la fin du pipeline après la première correspondance.

La seconde partie teste que nous avons réussi à obtenir un name non vide et, si tel est le cas, renomme le fichier zip:

[ "$name" ] && mv "" "${name%csv}zip"

Ce qui précède utilise suppression de suffixe pour changer le nom du fichier csv en un nom de fichier zip. ${name%csv} renvoie $name après avoir supprimé le suffixe csv . ${name%csv}zip ajoute un suffixe zip.

    
réponse donnée John1024 25.09.2015 - 01:32
la source

Lire d'autres questions sur les étiquettes