转载自:http://www.furion.info/81.html
周末看《sed 与 awk 第二版》的时候,看到书上有个很好的shell脚本-runsed,用来批量修改文件,当然是通过调用sed来修改。
原脚本代码如下:
# !/bin/bash
for x
do
echo “editing $x: \c”
if [ “$x” = sedscr ];
then
echo “not editing sedscript!”
elif [ -s $x ];
then
sed -f sedscr $x >/tmp/$x$$
if [ -s /tmp/$x$$ ];
then
if cmp -s $x /tmp/$x$$
then
echo “file not changed: \c”
else
mv $x $x.bak #save original ,just in case
cp /tmp/$x$$ $x
fi
echo “done”
else
echo “Sed produced an empty file \c”
echo “- check your sedscript.”
fi
rm -f /tmp/$x$$
else
echo “original file is empty.”
fi
done
echo “all done”
脚本的优点不用多说了,可以自动备份源文件、失败时候告警(提示empty)等。但也略微有不方便的地方:
1.无法指定sedsrc文件名
2.没有使用使用帮助
3.没有良好的参数处理
正好闲着无事,于是使用getopts加上了参数处理、使用帮助等。
#! /bin/bash
#this script is used for modified files by sed program
sedsrc=
files=
help=
#process the arguments
while getopts ‘s:f:h’ opt
do
case $opt in
s) sedsrc=$OPTARG
;;
f) files=${files}’ ‘${OPTARG}
;;
h) help=true
sedsrc=
file=
;;
esac
done
shift $(($OPTIND – 1))
#if got an -h argument ,print Usag end then efileit
if [ $help ];
then
echo “Usage: runsed -s sedcomand_file -f file1 -f file2 -f fileN ”
echo “Usage: runsed -h”
echo “-s, the sed command you want to efileec which store in a file ”
echo “-f, the file you want to process”
echo “-h, print the Usage”
printf “Example:\n”
printf “\t runsed -s sedsrc -f example \n”
exit 1
fi
if [ -z $sedsrc ] || [ -z “$files” ] ;
then
echo “empty sed command or process files !”
exit 1
fi
#process the sed command
for file in $files
do
echo “editing $file: \c”
if [ “$file” = sedscr ];
then
echo “not editing sedscript!”
elif [ -s $file ];
then
sed -f $sedsrc $file >/tmp/$file$$
if [ -s /tmp/$file$$ ];
then
if cmp -s $file /tmp/$file$$
then
echo “file not changed: \c”
else
mv $file $file.bak #save original ,just in case
cp /tmp/$file$$ $file
fi
echo “done”
else
echo “Sed produced an empty file \c”
echo “- check your sedscr file .”
fi
rm -f /tmp/$file$$
else
echo “original file is empty.”
fi
done
echo “all done”
使用了getops去处理参数,如果-s,-f为空,则报错;同时如果指定了-h参数则打印帮助手册,而不执行实际的修改操作。
if [ -z $sedsrc ] || [ -z “$files” ] ; 这里之所以使用”$files”的写法,因为files可能包含了多个文件参数,例如files= 1.test 2.test,如果直接使用[ -z $files] 则会报错:
binary operator expected
因此加上””引起来可以避免报错。
f) files=${files}’ ‘${OPTARG} ;这里采用了累加的形式存储多个文件到files变量中去。同时${OPTARG}是getops中 中的变量。
效果如下:
可以看出当缺少了-f或者-s参数均会报错,同时如果指定了-h参数则只打印帮助信息,而不实际执行修改。