
기본적으로, 나는 지속적으로 .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가 0이 아닌 값을 반환하지 않는 한 압축을 풀고 원본 아카이브를 삭제합니다. 폴더에 도달하면 함수가 자신을 호출하여 재귀적으로 발생합니다.
#!/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입니다. 이는 대부분 glob 패턴처럼 작동합니다.
이 줄은 local x=pwd f
이해하기 어려울 수 있지만 두 개의 로컬 변수를 정의합니다. 하나는 를 보유하기 위한 x pwd
이고 다른 하나는 초기화되지 않은 f입니다(아래 for 루프에서 초기화되었으므로 여기서는 로컬 변수로 선언했습니다).
함수가 사용하는 경우 를 저장 pwd
하고 다시 반환하는 것은 cd
좋은 일입니다(tm).
프로그래밍 방식 으로 의 출력을 사용하는 것은 ls
일반적으로 Bad Mojo이므로 해충처럼 피해야 합니다 find
.파일 이름에 공백이 포함되어 있으면 스크립트에서 ls를 사용하면 큰 시간이 걸립니다.당신은 경고를 받았습니다.
ZSH
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
}
그런 다음 해당 폴더 내부에서 호출하면 됩니다.