您的位置:首页 > 运维架构 > Shell

shell实现txt转换excel

2008-10-07 16:26 453 查看
转自:http://hi.baidu.com/yanweinet/blog/item/71a872d743d487d8a044dfe9.html

本程序要求用于转换的txt文本内数据用"|"线分隔,当然也可以根据自己的需要来修改,用"|"主要是因为很多时候提取的数据是用unload语句从数据库中提取的。

      这里要说明的是,单靠shell程序是不可能按照excel的真正的文件格式来写的,但是用这个程序转换的文本是能直接用windows下的excel程序打开的。估计已能基本满足一般的要求了。

      原理:将“|”分隔的数据最终换成以“  
”(tab制表符)分隔,文件名后缀改为.xls即可用windows下excel程序打开了。在这个程序里还解决了两个问题,第一个就是以"0"
开头的数字转换以后用excel打开后"0"会被自动删掉,再一个就是如果数字超过11位的长度则打开以后数据会自动用科学记数法表示。解决的办法就是在
这类数据前加" ' "(单引号),因为excel程序中如果在数字前加" '
"(单引号)则表示以文体格式存储数据。后来我测试的结果是打开的时候仍然能够看见在程序中添加的" '
"(单引号),在excel单元格双击这些数据后才会变为文本格式," '
"(单引号)消失。在我现在的应用中这也没什么大碍,因为这些数据本来就是文本样式的,不用参与做计算等,比如超过11位的一般就是身份证,以0开头的数
据则一般是状态标识。这样做以后我就可以拿这个程序来做批量转换,总比手工一个一个去用excel转换要轻松的多。

shell实现txt转换excel源程序如下:

#!/bin/sh
###############################################################################
#filename:toExcel
#功能:txt文本转换成excel,
#   txt文本内数据以"|"分隔
#
#帮助:toExcel -help OR toExcel --help
#
#input:
#1.单个文件处理的情况(参数个数可能:1、2)
#arg1:TXTfile (必须指定一存在文件)
#arg2:XLSfile (可以是一存在的存放目录,也可以是新的文件名,新的文件名
#可以带后缀也可以没有,但程序中最终会检查是否有后缀.xls,如果没有则
#会自动添加后缀.xls.如果这一参数是一目录, 程序则会修改原文件名后缀后?
#作为一新的文件名保存到指定目录。
#这一参数也可以不用输入,如果没有这个参数,新的文件则保存在TXT文件目录。
#2.批处理的情况(参数个数可能:2、3,其中第1个参数必为"-r")
#arg1: -r  (表示使用批处理)
#arg2:TXTfileDIR (该目录必须存在要转换的文件)
#arg3:XLSfileDIR (数据文件最终存放目录,如果没有这个参数则数据存放在当前目录)
#
#注:以"0"开头的数字 或者 长度超过11的数字,数据前加"'",
#  则数据将以文本格式保存,最终数据以制表符分隔,后缀名为.xls
#另:转换后的xls文件名
#重名时程序自动在新名字后加数字序号,但指定的文件名有重名则覆盖
###############################################################################

#帮助
help()
{
cat << EOF
帮助:
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ 一、单文件转换:                                               ┃
┃      toExcel arg1 arg2                                         ┃
┃      arg1:待转换文件                                           ┃
┃      arg2:转换后xls文件名(可带路径),或xls文件存放目录,如果  ┃
┃           这一参数为空则表示存放目录为待转换文件同一目录,这  ┃
┃           种情况下新文件名将使用旧文件名,后缀改为.xls。       ┃
┃ 二、批量转换("-r"):                                           ┃
┃      toExcel -r arg1 arg2                                      ┃
┃      arg1:待转换文件,可以是形如*.txt的表达式,也可以是一目录  ┃
┃           (将转换目录下所有文件)                               ┃
┃      arg2:转换后xls文件存放目录,这一参数为空则保存在待转换文 ┃
┃           件同目录                                             ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
EOF
}

#处理单个文件的转换
dealone()
{
if [ $# -ne 1 ] && [ $# -ne 2 ];then
echo "/nUsage: `basename $0` TXTfile XlSfile"
echo "OR: `basename $0` TXTfile saveDIR"
echo "OR: `basename $0` TXTfile /n"
help;
return 1;
fi

#帮助
if [ $# -eq 1 ];then
if [ "$1" = "-help" ] || [ "$1" = "--help" ];then
   help;
   return 0;
fi
fi

txtfile="$1" #txt文件
if [ ! -f $txtfile ];then
echo "<ERROR>TXT文件[$txtfile]不存在!"
help;
return 1;
fi

if [ $# -eq 2 ];then
xlsfile="$2"
else
xlsfile="`dirname $txtfile`"
fi

#最终保存的EXCEL文件的文件名
if [ -d $xlsfile ];then
#删除末尾"/"
xlsfile="`echo $xlsfile | sed 's///$//'`"
#将原文件修改后缀名为.xls作为最终EXCEL文件名
_tmpStr="` basename $txtfile | sed 's//.[^.]*$//' `"
_tmpStr2="$xlsfile/${_tmpStr}.xls"
#防止同名文件
i=1
while [ -f "$_tmpStr2" ]
do
   _tmpStr2="$xlsfile/${_tmpStr}($i).xls"
   i=`expr $i + 1`
done
xlsfile="$_tmpStr2"
else
#检查上级目录是否存在
if [ ! -d `dirname $xlsfile` ];then
   echo "<ERROR>指定文件[$xlsfile]上级目录不存在!"
   return 1;
fi
#检查指定名有无后缀.xls如果没有则加上
_tmpStr="` basename $xlsfile | grep ".xls$" `"
if [ "$_tmpStr" = "" ];then
   xlsfile="${xlsfile}.xls"
fi
fi

#补齐行首和行尾的"|"
#在形如"0123"等数据前加"'",避免导入Excel后前面的"0"被删
#在长度超过11的数字前加"'",避免导入Excel后变为科学记数法
#删除行首和行尾的"|"
#将"|"替换成" "(Tab)
sed 's/^[^|]/|&/g' $txtfile | sed 's/[^|] *$/&|/g' |
sed 's/| *0[0-9]/{1,/} *|/ &/g' | sed 's/| *[1-9][0-9]/{11,/} *|/ &/g' |
sed "s/ |/|/'/g" |
sed "s/^|//g" | sed "s/|$//g" |
sed 's/|/ /g' > $xlsfile

if [ $? -eq 0 ];then
echo "[$txtfile] -> [$xlsfile] OK !"
return 0;
else
echo "[$txtfile] -> [$xlsfile] ERROR !"
return 1;
fi
}

#非批量处理的参数情况
if [ $# -lt 2 ] || [ $# -gt 3 ] || [ "$1" != "-r" ];then
dealone $*
exit;
else
#批量处理的参数情况
TXTfileDIR="$2"
if [ ! -e "$TXTfileDIR" ];then
   echo "/n<ERROR>[$TXTfileDIR]不存在!/n"
   help;
   exit 1;
fi

if [ -d "$TXTfileDIR" ];then
   TXTfileDIR="`echo $2 | sed 's///$//'`"
   if [ "`find $TXTfileDIR -type f`" = "" ];then
    echo "/n<ERROR>目录[$TXTfileDIR]下不存在文件!/n"
    help;
    exit 1;
   fi
   TXTfileDIR="$TXTfileDIR/*"
fi

if [ $# -eq 3 ];then
   XLSfileDIR="`echo $3 | sed 's///$//'`"
   if [ ! -d $XLSfileDIR ];then
    echo "/n<ERROR>数据存放目录[$XLSfileDIR]不存在!/n"
    help;
    exit 1;
   fi
else
   XLSfileDIR=""
fi
fi

#批量处理,TXTfileDIR可以是存放要文件的一目录,也可以是类似"*.txt"等
for txt in $TXTfileDIR
do
if [ ! -f "$txt" ];then
   continue;
fi

dealone $txt $XLSfileDIR
if [ $? -ne 0 ];then
   echo "<ERROR>[$txt] deal failed !"
fi
done

exit 0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息