缓存转移开源

V1.0

首次上传

# by 酷安@于乐Yule
# 二改二传标明出处

# 输出目录
output="/storage/emulated/0/Download/缓存转移"

# 日志目录
log="$output/log.log"

# R · G · B
GR="\033[1;32m"     # 绿
YE="\033[1;33m"     # 黄
CY="\033[1;34m"     # 紫
BL="\033[1;36m"     # 蓝
RE="\033[1;31m"     # 红
WH="\033[1;37m"     # 白
BO="\033[1m"        # 粗体
RES="\033[0m"       # 结束

# 更符合中国宝宝阅读习惯的echo
yule() { 
    echo -e " $1"
}
yulen() { 
    echo -en " $1"
}
sepa() {
    echo "-------------------------------"
}
blank() {
    local n=${1:-1}
    if ! [[ "$n" =~ ^[0-9]+$ ]]; then
        echo "注意: 'blank'函数的参数不能为0或负数" >&2
        return 1
    fi
    for ((i=1; i<=n; i++)); do
        echo
    done
}

# json 阅读函数
jsonread() {
    local file_path="$1"
    local json_key="$2"
    if [ ! -f "$file_path" ]; then
        echo -n "错误:文件 $file_path 不存在。"
        return 1
    fi
    local value=$(grep -o "\"$json_key\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" "$file_path" | sed -n "s/.*: *\"\(.*\)\".*/\1/p")
    if [ -z "$value" ]; then
        echo -n "错误:未找到键 $json_key。"
        return 1
    else
        echo -n "$value"
    fi
}

# 日志输出函数
dlog() {
    local datetime=$(date +"%Y-%m-%d %H:%M:%S")
    local exit_status=$1
    echo "[$datetime] 操作: $exit_status" >> $log
}
errlog() {
    local datetime=$(date +"%Y-%m-%d %H:%M:%S")
    local exit_status=$1
    echo "[$datetime] 错误: $exit_status" >> $log
}
finlog() {
    local datetime=$(date +"%Y-%m-%d %H:%M:%S")
    local exit_status=$1
    echo "[$datetime] 完成: $exit_status" >> $log
}

# 卡死判断函数
jam() {
    local i
    local err_num_yule=$1
    if [[ $err_num_yule -lt "10" ]]; then
        for i in {0..4}; do
            printf "\033[1G"
            printf "\033[K"
            printf "\033[A"
        done
    else
        for n in {0..1}; do
            printf "\033[1G"
            printf "\033[K"
            printf "\033[A"
        done
    fi
    printf "\033[B\033[1G"
    yule "${RE}输入错误,请输入[1]/[2]/[3]${RES},你的输入:$2"
    yule "再错误$err_num_yule次会退出脚本"
}

# 微信操作部分函数
wechatdo() {
    sepa
    cd /data/data/com.tencent.mm/MicroMsg/${1}/attachment
    wechat_file_num=$(ls -C | wc -l)
    wechatfilecopy=$1
    ls -C
    sepa
    yule "共有:${YE}${wechat_file_num}个文件${RES}"
    yule "输入${YE}[y]${RES}进行确认,[n]取消"
    blank
    yulen "请输入: "
    read wechat_choice
    if [[ $wechat_choice == "y" ]]; then
        sepa
        yule "${CY}- 复制文件...${RES}"
        yulen "· 创建./微信/"
        mkdir "${output}/微信" 2>/dev/null
        yule "${GR} [完成]${RES}"
        yulen "· 移动文件到./微信/"
        cp /data/data/com.tencent.mm/MicroMsg/${wechatfilecopy}/attachment/* ${output}/微信 2>/${output}/error
        err=$?
        yule "${GR} [完成]${RES}"
        # 复制成功
        if [[ $err == "0" ]]; then
            yule "${GR}· 复制完成${RES}"
            sepa
            if [[ $delete == "yes" ]]; then
                rm -rf $dir/*
                yule "${GR}删除源文件成功${RES}"
            fi
            finlog "[$name]转移成功"
            yule "${GR}已完成转移${RES}"
            yule "路径${output}/$name"
        # 复制失败,输出日志
        else
            blank
            sepa
            blank 2                        
            errtext=$(cat ${output}/error)           
            yule "ERR: $errtext"
            errlog "[$name]复制文件失败: $errtext"
            blank 2
            yule "${RE}· 复制出错,请检查:${RES}"
            yule "  1.存储空间是否足够"
            yule "  2.是否未下载文件"
            yule "  3.软件是否为旧版"
            yule "  4.是否未授权Root"
        fi        
    elif [[ $wechat_choice == "n" ]]; then
        exit 0
    else
        blank
        yule "${RE}输入错误${RES}"
        exit 0
    fi
}

# 哔哩哔哩操作函数
bilido() { 
    clear
    blank 2
    find "$dir" -maxdepth 10 -type f -name 'entry.json' | while read -r filedir; do
        prev=$(dirname ${filedir})
        foldersize=$(du -sh $prev 2>/dev/null | cut -f1 2>/dev/null)
        echo "$filedir" >> ${output}/bili
        nowwechatnum=$(cat ${output}/bili | wc -l)
        yulen "$nowwechatnum"
        yule "${CY}$(jsonread $filedir "title")${RES} | ${YE}$foldersize${RES}"
    done
    sepa
    yule "找到 ${YE}$(cat ${output}/bili | wc -l)${RES} 个视频"
    yule "${GR}[y]确定开始${RES}   ${RE}[n]取消并退出${RES}"
    read bili_choice
    rm -f ${output}/bili
    if [[ $bili_choice == "y" ]]; then
        # 转移步骤
        # 创建视频同名文件夹
        sepa
        mkdir ${output}/哔哩哔哩
        find "$dir" -maxdepth 10 -type f -name 'entry.json' | while read -r filedir; do
            folder_name=$(jsonread $filedir "title")
            mkdir ${output}/哔哩哔哩/${folder_name} 2>/dev/null
            # 复制 m4s 和 json 文件到目录
            prev=$(dirname ${filedir})
            audio=$(find "$prev" -maxdepth 10 -type f -name 'audio.m4s')
            cp $audio ${output}/哔哩哔哩/${folder_name} 2>/dev/null
            video=$(find "$prev" -maxdepth 10 -type f -name 'video.m4s')
            cp $video ${output}/哔哩哔哩/${folder_name} 2>/dev/null
            danmaku=$(find "$prev" -maxdepth 10 -type f -name 'danmaku.xml')
            cp $danmaku ${output}/哔哩哔哩/${folder_name} 2>/dev/null
            info=$(find "$prev" -maxdepth 10 -type f -name 'entry.json')
            cp $info ${output}/哔哩哔哩/${folder_name} 2>/dev/null
        done
        if [[ $delete == "yes" ]]; then
            rm -rf $dir/*
        fi
        finlog "[哔哩哔哩]转移成功"
    else
        exit 0
    fi
}

# 脚本操作部分
    # dir:文件路径
    # type:
        # 1 表示目录用文件夹进行了分类,此时下面的suf不生效
        # 0 表示文件夹内就是要移动的文件
    # suf:要搜寻的文件后缀名,type 为 1 时不生效,使用 | 分割,all 表示所有文件
main() {
    # 定义哔哩哔哩的信息
    if [[ $menu == "1" ]]; then
        name="哔哩哔哩"
        dir="/storage/emulated/0/Android/data/tv.danmaku.bili/download/"
        type="1" # 哔哩哔哩对视频做了文件夹区分
        suf=".m4s|.json"
    # 定义微信的信息
    elif [[ $menu == "2" ]]; then
        name="微信"
        dir="/data/data/com.tencent.mm/MicroMsg/"
        type="1" # 微信对账号做了文件夹区分
        suf="wechat file"
    # 定义QQ的信息
    elif [[ $menu == "3" ]]; then
        name="QQ"
        dir="/storage/emulated/0/Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/"
        type="0" # 排除子文件夹
        suf="all"
    # 定义Nekogram的信息
    elif [[ $menu == "4" ]]; then
        name="Nekogram"
        dir="/storage/emulated/0/Android/data/tw.nekomimi.nekogram/files/Telegram/"
        type="1"
        suf="all"
    fi
    main2
}
    
main2() {
    blank 2
    yule "${YE}你选择了${RES} [${BL} $name ${RES}]"
    if [[ $menu != "2" ]]; then
        size=$(du -sh "$dir" | cut -f1)
        yule "${BL}目录大小:${size}${RES}"
    fi      
    blank
    
    # 询问用户是否要删除源文件
    yulen "是否${RE}删除原文件${RES} (yes / no): "
    read delete    
    blank
    case $delete in
        yes)
            yule "操作完成后会删除源文件哦"
            ;;
        no)
            yule "操作完成后不会删除源文件哦"
            ;;
        *|\n)
            yule "输入错误,奖励退出脚本哦"
            exit 1
            ;;
    esac
    main3
}

main3() {
    # 面向 type 0 | suf all 进行操作
    if [[ $type == "0" && $suf == "all" ]]; then
        sepa
        yule "${CY}- 复制文件...${RES}"
        yulen "· 创建./$name/"
        mkdir "${output}/$name" 2>/dev/null
        yule "${GR} [完成]${RES}"
        yulen "· 移动文件到./$name/"
        find $dir -maxdepth 1 -type f -exec cp {} ${output}/$name \; 2>/${output}/error
        err=$?
        yule "${GR} [完成]${RES}"
        # 复制成功
        if [[ $err == "0" ]]; then
            yule "${GR}· 复制完成${RES}"
            sepa
            if [[ $delete == "yes" ]]; then
                rm -rf $dir/*
                yule "${GR}删除源文件成功${RES}"
            fi
            finlog "[$name]转移成功"
            yule "${GR}已完成转移${RES}"
            yule "路径${output}/$name"
        # 复制失败,输出日志
        else
            blank
            sepa
            blank 2                        
            errtext=$(cat ${output}/error)           
            yule "ERR: $errtext"
            errlog "[$name]复制文件失败: $errtext"
            blank 2
            yule "${RE}· 复制出错,请检查:${RES}"
            yule "  1.存储空间是否足够"
            yule "  2.是否未下载文件"
            yule "  3.软件是否为旧版"
            yule "  4.是否未授权Root"
            exit 1
        fi
        
    # 面向 type 1 | suf all 进行操作
    elif [[ $type == "1" && $suf == "all" ]]; then
        sepa
        yule "${CY}- 复制文件...${RES}"
        yulen "· 创建./$name/"
        mkdir "${output}/$name" 2>/dev/null
        yule "${GR} [完成]${RES}"
        yulen "· 移动文件到./$name/"
        cp -r ${dir}* ${output}/${name} 2>/${output}/error
        err=$?
        yule "${GR} [完成]${RES}"
        # 复制成功
        if [[ $err == "0" ]]; then
            yule "${GR}· 复制完成${RES}"
            sepa
            if [[ $delete == "yes" ]]; then
                rm -rf $dir/*
                yule "${GR}删除源文件成功${RES}"
            fi
            finlog "[$name]转移成功"
            yule "${GR}已完成转移${RES}"
            yule "路径${output}/$name"
        # 复制失败,输出日志
        else
            blank
            sepa
            blank 2                        
            errtext=$(cat ${output}/error)           
            yule "ERR: $errtext"
            errlog "[$name]复制文件失败: $errtext"
            blank 2
            yule "${RE}· 复制出错,请检查:${RES}"
            yule "  1.存储空间是否足够"
            yule "  2.是否未下载文件"
            yule "  3.软件是否为旧版"
            yule "  4.是否未授权Root"
            exit 1
        fi

    # 面向 微信 的操作
    elif [[ $name == "微信" ]]; then
        clear
        blank 2
        cd $dir 2>/dev/null
        foldernum=$(find "$dir" -maxdepth 1 -type d -name "????????????????????????????????" | wc -l)
        if [[ $foldernum -gt "1" ]]; then
            yule "${BL}您登录过 $foldernum 个微信号,产生了多个目录${RES}"
            sepa
            yule "请选择一个目录进行查看:"
            find "$dir" -maxdepth 1 -type d -name "????????????????????????????????" | while read -r folderdir; do
                foldername=$(basename $folderdir)
                foldersize=$(du -sh ${folderdir}/attachment 2>/dev/null | cut -f1 2>/dev/null)
                if [[ $foldersize == "" ]]; then
                    foldersize="0KB"
                fi
                echo "$foldername" >> ${output}/wechat
                nowwechatnum=$(cat ${output}/wechat | wc -l)
                yulen "${BL}[$nowwechatnum]"
                yule "账号:${CY}$foldername${RES} | ${YE}$foldersize${RES}"
            done
            yule "- 当前脚本版本最多可支持6个微信号"
            sepa
            yulen "请输入[序号]: "
            read wechat_account
            case $wechat_account in
                1)
                    account_c=$(sed -n "1p" "${output}/wechat")
                    yule "你选择了 ${BL}${account_c}${RES}"
                    wechatdo ${account_c}
                    ;;
                2)
                    account_c=$(sed -n "2p" "${output}/wechat")
                    yule "你选择了 ${BL}${account_c}${RES}"
                    wechatdo ${account_c}
                    ;;
                3)
                    account_c=$(sed -n "3p" "${output}/wechat")
                    yule "你选择了 ${BL}${account_c}${RES}"
                    wechatdo ${account_c}
                    ;;
                4)
                    account_c=$(sed -n "4p" "${output}/wechat")
                    yule "你选择了 ${BL}${account_c}${RES}"
                    wechatdo ${account_c}
                    ;;
                5)
                    account_c=$(sed -n "5p" "${output}/wechat")
                    yule "你选择了 ${BL}${account_c}${RES}"
                    wechatdo ${account_c}
                    ;;
                6)
                    account_c=$(sed -n "6p" "${output}/wechat")
                    yule "你选择了 ${BL}${account_c}${RES}"
                    wechatdo ${account_c}
                    ;;
                *)
                    yule "${RE}选择错误或超出最大账号限制${RES}"
                    exit 1
                    ;;
            esac
            rm -f ${output}/wechat
        else
            exit 0
        fi

    # 面向哔哩哔哩的操作
    elif [[ $name == "哔哩哔哩" ]]; then
        bilido
    fi
    
    # 生成本次配置的 json
    touch ${output}/last.json
    echo "{\"name\":\"$name\",\"type\":\"$type\",\"suf\":\"$suf\",\"dir\":\"$dir\",\"del\":\"$delete\",\"data\":\"$(date +"%Y-%m-%d %H:%M:%S")\"}" > ${output}/last.json
    rm -f ${output}/error
    exit 0
}

# 脚本菜单部分
menu() {
    yule "${YE}欢迎使用《缓存转移》${RES}"
    sepa
    yule "${BL}- 哔哩哔哩    [1]${RES}"
    yule "${BL}- 微信        [2]${RES}"
    yule "${BL}- QQ          [3]"
    yule "${BL}- Nekogram    [4]${RES}"
    # 选择菜单
    for err_num_2 in {10..0}; do
        sepa
        yulen "请输入[1]/[2]/[3]/[4]:"    
        read menu_2
        case $menu_2 in
            1)
                # 哔哩哔哩
                menu=1
                main
                ;;
            2)
                # 微信
                menu=2
                main
                ;;
            3)
                # QQ
                menu=3
                main
                ;;
            4)
                # Nekogram
                menu=4
                main
                ;;
            *|\n)
                # 输入错误
                jam $err_num_2 $menu_2
                ;;
        esac
    done
}

# 主标题:CY
# 副标题:YE
# 三级文字:BL
# 文字:WH (没有)

# 脚本介绍
mkdir "${output}"
echo "$log"
touch /storage/emulated/0/Download/缓存转移/log.log
if [ -e "$log" ]; then
    echo "日志文件存在"
else
    touch "$log"
fi
rm -f ${output}/wechat
rm -f ${output}/bili
rm -f ${output}/error
clear

# 读取上一次保存的配置
if [[ -e "${output}/last.json" ]]; then
    blank 2
    yule "上次配置:"
    yulen ""
    jsonread ${output}/last.json "data"
    blank 2
    yule "${YE}应用名:${RES}"
    yulen ""
    jsonread ${output}/last.json "name"
    blank 2
    yule "${YE}路径:${RES}"
    yulen ""
    jsonread ${output}/last.json "dir"
    blank 2
    yule "${YE}是否已分类:${RES}"
    yulen ""
    jsonread ${output}/last.json "type"
    blank 2
    yule "${YE}移动的文件后缀:${RES}"
    yulen ""
    jsonread ${output}/last.json "suf"
    blank 2
    yule "${YE}完成后删除源文件:${RES}"
    yulen ""
    jsonread ${output}/last.json "del"
    blank 2
    sepa
    yulen "要用上一次的配置吗(yes / no): "
    read last
    if [[ $last == "yes" ]]; then
        name=$(jsonread ${output}/last.json "name")
        dir=$(jsonread ${output}/last.json "dir")
        type=$(jsonread ${output}/last.json "type")
        yule "$type"
        sleep 5
        delete=$(jsonread ${output}/last.json "del")
        suf=$(jsonread ${output}/last.json "suf")
        yule "跳转到main3..."
        main3
    fi
fi

# 介绍
clear
blank 2
yule "${YE}本脚本可以将应用所下载的文件转移到你设定的目录${RES}"
blank
yule "${BL}已支持应用:${RES}"
yule "- 哔哩哔哩"
yule "- 微信"
yule "- QQ"
yule "- Nekogram"
blank
sepa
yulen "${GR}开始[1]${RES}"
yulen "${RE}  退出[2]${RES}"
yule "${CY}  配置路径[3]${RES}"
yule "${BL}    我要学习自己适配应用[4]${RES}"

# 选择开始菜单
for err_num in {10..0}; do
    sepa
    yulen "请输入[1]/[2]/[3]/[4]:"
    read menu_1 
    case $menu_1 in
        1)
            # 开始
            clear
            blank 2
            menu
            exit 0
            ;;
        2)
            # 退出
            blank
            yule "${GR}脚本已退出,欢迎下次使用${RES}"          
            exit 0
            ;;
        3)
            # 配置路径
            clear
            blank 2
            yulen "功能研发中,请编辑脚本顶部的 output= 进行配置"
            exit 0
            ;;
        4)
            # 使用浏览器打开教程
            am start -a android.intent.action.VIEW -d "https://baidu.com/"
            exit 0
            ;;
        *|\n)
            # 输入错误
            jam $err_num $menu_1
            ;;
    esac
done

blank
yule "${RE}你已连续输入错误10次,被系统判定为卡死,已退出脚本"