
基本上,我有一組不斷充滿 .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
}
然後只需從相應的資料夾中調用它即可。