#!/bin/bash
# filelist 变量设定你所需要检查的压缩文件列表(绝对路径),可以通过find . -name '*.zip' | sort | uniq > testfile。与脚本在相同目录下
# existlist 变量是从filelist文件中得到的包含特定文件的列表,脚本执行完后可以查看
# errorlist 变量是从filelist文件列表中得到的不包含特定文件的列表,当然也有可能这个压缩文件本身不完整
# filebak 变量指定要替换的那个压缩文件备份的目录
# oldfile 指定要替换的那个文件名
# newfile 指定新文件的文件名,注意这个文件一定要在脚本当前目录下
# binrar,bin7z 指定解压缩命令目录,因为7z和rar都不是CentOS自带的
# fl 是filelist文件列表里的每一条记录
# exist 压缩文件fl的内容列表里包含oldfile.ini的记录,可能有多行
# dirfiles 处理exist的结果,形如压缩包里的目录结构 your/dir/oldfile.ini,可能有多行
# df 是dirfiles中的单行记录,它的前面目录部分便是tmp_dir
# 是否有必要root用户执行看个人情况,执行后部分文件的属主可能会变,可用chown user1.user1 -R /your/dir/恢复
# 有部分zip文件无法使用7z,但文件本身正常,从日志可以看到error信息
# oldfile.ini区分大小写,如果要查找替换oldfile.ini请修改后在执行(确保grep没有-i选项)
# 可以处理的情况
# 压缩文件中无oldfile.ini
# 要替换的oldfile.ini文件在压缩文件根目录下
# 要替换的oldfile.ini在嵌套子目录中
# 压缩文件中存在多个oldfile.ini
# 压缩文件本身存在问题
#该脚本有一定的危险性(虽然已备份),在正式环境中运行之前一定要多做测试。并且运行一次之后,谨慎运行第二次,因为可能会导致备份被覆盖(可换备份目录)
# 假如出现异常,要从备份文件恢复所有修改的文件,可以根据$existlist和filebak下的目录列表拼凑cp语句
# 建议执行方法./rar_new.sh | tee your.log,事后可从your.log中查看日志
# filelist="test_filelist"
filelist="testfile"
existlist="${filelist}.exist"
errorlist="${filelist}.not"
filebak="zipbak"
oldfile=oldfile.ini
newfile=newfile.ini
bin7z="/usr/bin/7z"
export LANG="zh_CN.GB18030"
IFS=$'\n'
echo "files list bellow have ${oldfile}:" > $existlist
echo "files list bellow do not have ${oldfile} or may have error:" > $errorlist
for fl in `cat $filelist`
do
# ${oldfile} exist or not, file error or not
exist=`$bin7z l $fl |grep ${oldfile}`
if [ $? -ne 0 ];then
echo "$fl" >> $errorlist
continue
else
# get extracting dir and filename, could be more than one file
dirfiles=`echo "$exist" | awk '{for (i=6;i<=NF;i++) printf $i" " ; print ""}'`
fi
# echo ===== "$dirfiles"
if [ "$dirfiles" != "" ];then
echo "$fl" | tee -a $existlist
# backup original file
/bin/cp -af "$fl" "$filebak/"
echo "--- $fl is backed up in $filebak"
echo " $dirfiles"
for df in `echo "$dirfiles"`
do
# create temp directory to put new ${newfile} for compress
tmp_dir=$( echo "$df" | awk -F '/' '{for(i=1;i<NF;i++) printf"%s/",$i} {print ""}' )
if [ ${#tmp_dir} -ne 0 ];then
mkdir -p "$tmp_dir" && cp -af ${newfile} "$tmp_dir"
fi
# start delete old file and add new one
$bin7z d "$fl" "$tmp_dir"${oldfile} > /dev/null && $bin7z a "$fl" "$tmp_dir"${newfile} > /dev/null
if [ $? -ne 0 ];then
echo "--- zip file $fl may have error, you SHOULD check it"
fi
if [ ${#tmp_dir} -ne 0 ];then
rm -f "$tmp_dir"${newfile} && rmdir -p "$tmp_dir"
if [ $? -ne 0 ];then
echo "--- tmp_dir $tmp_dir delete fail"
fi
fi
done
echo "--- old deleted, new added"
fi
done