Rekursives Unrar mit anschließendem Löschen

Rekursives Unrar mit anschließendem Löschen

Im Grunde habe ich eine Reihe von Verzeichnissen, die ständig mit .rar-Dateien gefüllt werden, und ich muss in der Lage sein, sie an Ort und Stelle zu extrahieren, wobei die übrig gebliebenen .(rar|rXX)-Dateien automatisch gelöscht werden. Wie gehe ich dabei vor?

Hinweis: Ich kann sie nicht alle löschen, wenn sie einmal fertig sind. Sie müssen gelöscht werden, wenn das Skript einen seltenen Satz abschließt.

Beispiel einer Verzeichnisstruktur:

/
/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

Erwartetes Ergebnis:

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

Antwort1

Variante für 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

RAR-Archive können auch "legal" benannt werden, z. B. myarchive.part001.rarund so weiter, und das müsste separat behandelt werden, wenn diese Art von Archiven existiert. Eine pragmatische Lösung besteht darin,

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

mit

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

Beachten Sie jedoch, dass hierdurch RAR-Dateien gelöscht werden, selbst wenn der Fehlercode 10 („Keine zu extrahierenden Dateien“) angezeigt wird. Daher wird die unveränderte Form im Allgemeinen nicht empfohlen.


Alles in allem ist es vielleicht besser, das Material einfach in der archivierten Form zu speichern und stattdessen bei Bedarf eine sofortige Dekomprimierung oder etwas Ähnliches zu verwenden. Das Beibehalten des archivierten Formats kann noch weitere Vorteile haben.

Antwort2

Ich schreibe das aus dem Stegreif, es ist also ungetesteter Code, aber er sollte Sie auf den richtigen Weg bringen. Er durchläuft im Grunde den Baum, auf den Sie zeigen, und sucht nach .rar-Dateien. Wenn er eine findet, wird er sie an Ort und Stelle dekomprimieren und das Originalarchiv löschen, es sei denn, unrar gibt einen Wert ungleich Null zurück. Wenn ein Ordner gefunden wird, ruft sich die Funktion einfach selbst auf, was sie rekursiv macht.

#!/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"

Der Funktionsname ist völlig beliebig. Ich möchte, dass sie sich wie richtiges Englisch lesen, wenn sie mit ihren Argumenten aufgerufen werden. [[ -d /path ]]Gibt „true“ zurück, wenn der Pfad existiert und ein Verzeichnis ist. -fMacht das Entsprechende für Dateien. [[ "string" =~ "pattern"]]ist ein Bashismus, der Mustervergleiche in Zeichenfolgen ermöglicht. Es funktioniert größtenteils genau wie Glob-Muster.

Die Zeile local x=pwd fmag kryptisch sein, aber sie definiert lediglich zwei lokale Variablen: eine namens x, um das zu speichern pwd, und eine namens f, nicht initialisiert (sie wird in der for-Schleife unten initialisiert, ich deklariere sie hier nur, damit sie lokal ist).

Das Speichern pwdund Zurückkehren dazu, wenn Ihre Funktion es verwendet, cdist eine gute Sache (tm).

Bitte beachten Sie, dass die programmgesteuerte Verwendung der Ausgabe von lsim Allgemeinen ein schlechtes Omen ist und Sie es wie die Pest zugunsten von vermeiden sollten find.Wenn einer Ihrer Dateinamen ein Leerzeichen enthält, führt die Verwendung von „ls“ in Ihrem Skript zu großen Problemen.Du wurdest gewarnt.

ZSH

Ich bin nicht sicher, ob Sie dasselbe in Bash tun können, aber in ZSH würde ich das Folgende irgendwo einfügen.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
}

Und rufen Sie es dann einfach aus dem entsprechenden Ordner heraus auf.

verwandte Informationen