1 votes

Déchiffrage récursif avec suppression au fur et à mesure de la progression

En gros, j'ai un ensemble de répertoires qui sont constamment remplis de fichiers .rar, et je dois pouvoir les extraire sur place en supprimant automatiquement les fichiers .(rar|rXX) restants. Comment dois-je m'y prendre ?

Note : Je ne peux pas tous les supprimer une fois qu'ils sont faits, ils doivent être supprimés au fur et à mesure que le script complète un ensemble rar.

Exemple de structure de répertoire :

/
/folder1/
        /file1.rar
        /file1.r00
        /file1.r01
/folder2/
        /sub.folder1/
                    /file2.part001.rar (contains a directory "file2")
                    /file2.part002.rar
                    /file2.part003.rar
        /sub.folder2/
                    /file3.rar
                    /file3.r00
                    /file3.r01

Résultat escompté :

/
/folder1/
        /file1.ext
/folder2/
        /sub.folder1/
                    /file2/
                          /file2.ext
        /sub.folder2/
                    /file3.ext

3voto

Daniel Andersson Points 22765

Variante pour Bash :

#!/bin/bash
if [ ! -d "${1}" ]; then
    printf '%s: error: mandatory argument is not a valid directory.' "${0##*/}" 1>&2
    exit 1
fi

shopt -s extglob
for i in "${1}"/**/*.rar; do
    cd -- "${i%/*}"
    file=${i##*/}
    unrar e -- "${file}" && rm -- @(${file}|${file%.rar}.r[[:digit:]][[:digit:]])
    cd - >/dev/null
done

Les archives RAR peuvent également être nommées "légalement", par exemple. myarchive.part001.rar et ainsi de suite, et cela devrait être traité séparément d'une certaine manière si ce genre d'archives existe. Une manière pragmatique de résoudre ce problème est de remplacer

unrar e -- "${file}" && rm -- @(${file}|${file%.rar}.r[[:digit:]][[:digit:]])

avec

unrar e -o- -- "${file}"
if [ $? -eq 0 -o $? -eq 10 ]; then
    rm -- @(${file}|${file%.rar}.r[[:digit:]][[:digit:]])
fi

mais attention, cela nettoiera les fichiers RAR même si le code d'erreur 10 ("Aucun fichier à extraire") est donné, et n'est donc pas généralement recommandé dans sa forme non modifiée.


En somme, il serait peut-être préférable de simplement stocker le matériel sous forme archivée et d'utiliser la décompression à la volée ou quelque chose de similaire lorsque vous souhaitez l'utiliser. Il peut y avoir d'autres avantages à conserver le format archivé.

1voto

mkaito Points 1892

J'écris ceci à partir de ma tête, donc c'est un code non testé, mais cela devrait vous mettre sur la bonne voie. En gros, il parcourt l'arbre que vous lui indiquez, à la recherche de fichiers .rar. Lorsqu'elle en trouve un, elle le décompresse sur place et supprime l'archive originale, sauf si unrar renvoie un résultat différent de zéro. Si elle trouve un dossier, la fonction s'appelle elle-même, ce qui la rend récursive.

#!/bin/bash

[[ ! -d "$1" ]] && echo "Please point me at a directory!" && exit 1

function recursively_extract_all_rars_in() {
    local x=`pwd` f
    cd "$1"

    for f in (*); do
        [[ -d "$f" ]] && recursively_extract_all_rars_in "$f"
        [[ -f "$f" ]] && [[ "$f" =~ "*.rar" ]] && unrar e "$f" && rm ${f%%.*}.r??
    done
    cd "$x"
}

recursively_extract_all_rars_in "$1"

Le nom de la fonction est complètement arbitraire. J'aime qu'elles se lisent comme du bon anglais lorsqu'elles sont invoquées avec leurs arguments. [[ -d /path ]] renvoie vrai si le chemin existe et est un répertoire. -f fait la même chose pour les fichiers. [[ "string" =~ "pattern"]] est un bashisme qui permet de faire du pattern matching dans les chaînes de caractères. Il fonctionne essentiellement comme les motifs globaux.

La ligne local x=pwd f peut sembler énigmatique, mais il définit simplement deux variables locales : une appelée x, pour contenir la variable pwd et un appelé f, non initialisé (il est initialisé dans le boucle for ci-dessous, je le déclare juste ici pour qu'il soit local).

Stocker le pwd et y revenir si votre fonction utilise cd est une bonne chose (tm).

Veuillez noter qu'en utilisant la sortie de ls de manière programmatique est généralement une mauvaise chose, et vous devriez l'éviter comme la peste, en faveur de find . Si l'un de vos noms de fichiers contient un espace, l'utilisation de ls dans votre script sera un gros problème. Vous avez été prévenus.

ZSH

Je ne suis pas sûr que vous puissiez faire la même chose en Bash, mais en ZSH, je mettrais ce qui suit quelque part dans le fichier .zshrc

function recursive_unrar() {
    for f in **/*.rar; do
        local cwd=`pwd` fbn=${f##*/}
        cd "${f%/*}"
        unrar e "$fbn"
        rm "${fbn%%.*}.r{01..99} $fbn"
        cd "$cwd"
    done
}

Et ensuite, il suffit de l'appeler depuis le dossier correspondant.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X