Shell学习笔记(16)-最后一个练习

在etl目录下有若干个ktr文件,每个ktr文件中都包含一些dbip,dbsid,username,passwd等配置信息,这个shell的脚本是根据配置文件修改这些ktr文件的配置信息.


配置文件config.txt的设计如下:

server:10.10.224.99:10.10.224.100
database:popdb:lotterydb
username:jdlottery:jdlottery
password:'Encrypted 2be98afc86aa7828bbb15a164ca97bdc4':'Encrypted 2be98afc86aa7828bbb15a164ca97bdc4'


格式采用  元素名:原始值:改之后的值.

其中password的值中含有空格,用' '括起来表示这是一个整体.



shell文件:

#! /bin/bash
#build.sh用于根据config.txt的配置信息更改*.ktr的connection信息,并执行*.ktr完成统计工作

#shopt -s -o nounset

ktrFiles=$(ls *.ktr)

#备份
echo "开始备份...."
[ -d back-up ] || mkdir back-up
timeStamp=_$(date +%Y%m%d_%H%M%S)
for ktrfile in ${ktrFiles}
do
    cp ./${ktrfile}  ./back-up/${ktrfile}${timeStamp}
done
echo "备份结束"

#参数替换
echo "参数替换...."
declare -i num
declare -i i=1
eval $(wc -l config.txt | awk '{printf("num=%s\n"),$1}')
while((i<=num))
do
    eval $(awk -F: 'NR=="'$i'"{printf("para"'$i'"_name=%s\npara"'$i'"_value_old=%s\npara"'$i'"_value_new=%s\n"),$1,$2,$3}' config.txt )
#    name=para${i}_name
#    echo ${name}:${!name}
#       value_old=para${i}_value_old
#       echo ${value_old}:${!value_old}
#       value_new=para${i}_value_new
#       echo ${value_new}:${!value_new}

#       eval echo \$$name    

         let i++
done

replace(){
    if [ $# -ne 4 ]; then
        echo "使用法: $FUNCNAME 文件名 属性名 原始值 新值"
        return 1
    fi
    
    [ -a $1 ] || (echo "$1不存在!";return 2)

    content_old="<$2>$3</$2>"
    content_new="<$2>$4</$2>"
#    local -i i=$(sed -n s/${content_old}/p $1 | wc -l)
    local -i i=$(cat $1 | grep "${content_old}" | wc -l)
    echo "$1存在${content_old}的个数为:$i"
    if((i<1));then
        echo "$1不存在属性元素:$content_old."
        return 3
    fi

    [ -d tmp ] || mkdir tmp
    tmp_file="./tmp/tmp.$$"
    sed s#"${content_old}"#"${content_new}"#g $1 > ${tmp_file}
    mv -f ${tmp_file} $1
    echo "$1文件 原内容$content_old替换成$content_new!"
    
}

for ktrfile in ${ktrFiles}
do
    i=0
    while((i<=num))
    do
    let i++
        name=para${i}_name
        value_old=para${i}_value_old
        value_new=para${i}_value_new
#        [ ${!value_old} == ${!value_new} ] && continue || replace ${ktrfile} ${!name} ${!value_old} ${!value_new}
    if [ "${!value_old}" == "${!value_new}" ];then
        continue
    else
        replace ${ktrfile} ${!name} "${!value_old}" "${!value_new}"
        if [ $? -ne 0 ];then
            echo "=======================ERROR!========================"
            exit 1;
        fi        
    fi
    done
done
echo "替换结束"

1.这个实例中涉及到的最复杂最麻烦的东东就是'和"以及空格、特殊字符等的处理,这个详细参照shell十三问的解答吧。

2.shell变量和sed、awk变量的交互也不是个容易的东东,但原理和'和"的区别是一致的.

3.sed 替换的内容中有特殊内容的问题.如是< > / 空格,最坑爹是替换的内容中含有/s。(</server>中就包含/s)


不过如果你搞明白了shell内容对IFS、单引号、双引号、escape(转义)字符的处理方式,上面三个问题就都不是问题啦。

shell十三问中对单引号和双引号的区别的解释堪称经典中的经典,细细品味吧.


你可能感兴趣的:(Shell学习笔记(16)-最后一个练习)