遞歸解壓縮並在進行過程中進行刪除

遞歸解壓縮並在進行過程中進行刪除

基本上,我有一組不斷充滿 .rar 的目錄,我需要能夠透過自動刪除剩餘的 .(rar|rXX) 檔案來將它們提取到位。我該怎麼辦?

注意:完成後我無法刪除所有這些文件,必須在腳本完成一組 rar 後將其刪除。

目錄結構範例:

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

預期結果:

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

答案1

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 存檔也可以「合法」命名,例如myarchive.part001.rar等等,如果存在這些類型的存檔,則必須以某種方式單獨處理。解決這個問題的一個實用方法是替換

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

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

但請注意,即使給出錯誤代碼 10(「沒有要提取的文件」),這也會清除 RAR 文件,因此通常不建議以其未修改的形式進行。


總而言之,最好只是將材料以存檔形式存儲,然後在需要使用時使用即時解壓縮或類似的方法。保留存檔格式可能還有其他好處。

答案2

我是憑空寫下這段程式碼的,所以它是未經測試的程式碼,但它應該能讓你走上正軌。它基本上會遍歷您指向的樹,尋找 .rar 檔案。找到一個後,它將就地解壓縮並刪除原始存檔,除非 unrar 返回非零。當點擊一個資料夾時,該函數只會呼叫自身,從而導致它是遞歸的。

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

函數名稱完全是任意的。我喜歡讓他們在引用他們的論點時像正確的英語一樣讀起來。[[ -d /path ]]如果路徑存在且是目錄,則傳回 true。-f為文件做對應的操作。[[ "string" =~ "pattern"]]是一種允許在字串中進行模式匹配的 bashism。它的工作原理與全局模式基本相同。

該行local x=pwd f可能很神秘,但它只定義了兩個局部變數:一個稱為 x,用於保存pwd,另一個稱為f,未初始化(它在下面的for 循環中初始化,我只是在這裡聲明它,因此它是本地的)。

儲存pwd並返回它(如果您的函數使用)cd是一件好事(tm)。

請注意,以程式設計方式使用 的輸出ls通常是 Bad Mojo,您應該像害蟲一樣避免它,而應該使用find.如果任何檔案名稱包含空格,在腳本中使用 ls 將會搞砸。你被警告了。

中興

我不確定你可以在 Bash 中做同樣的事情,但是在 ZSH 中,我將以下內容放在.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
}

然後只需從相應的資料夾中調用它即可。

相關內容