前言:最近项目开发中需要用到shell脚本来对文件进行处理,之前也没有写过shell脚本,借此机会学习了一下。需求是这样的,对下载好的数据文件进行重命名以及替换文件中的分割符,这个需求看似简单,但是对于没有接触过shell脚本的同志来说还是有点难整的,可能也是一通百度,然后也整出来了,但是发现用java程序调用脚本执行的时候又报错,非常的苦恼!但是就也是收获一个新知识新技能的机会。以前没接触过或者使用起来不流程,问题摆出,那就是你对这个不熟悉,得补课。无论是初次学,还是重修补课,都是工作经验和专业知识的积累。等将来你跳槽面试时,面试官问你对linux命令了解多少,你就可以告诉他我会写shell脚本,如果你学的比较好,你就告诉面试官,我会用户shell脚本搭建出服务器环境,那面试官基本会很满意你的回答。
需求分析
说明:使用shell脚本来处理文件是系统某一个业务功能的一部分,其中包含有很多流程,有文件下载、数据导入、数据加工等一系列功能。而我们这个功能是位于文件下载和数据导入之间,因为不想对原有的程序进行修改,而文件又是其他系统提供的,对现有程序不太“友好”,因此需要使用shell脚本来进行处理一下。
其他系统提供的文件有3类,.dat文件、chk文件和.ok文件,这是原程序正常处理的文件,但是现在其他系统只提供了两类文件,.dat文件和.ok文件,而且.dat文件也没有遵守之前的约定,需要我们进行处理后才能使用原来的程序进行处理。
实现逻辑
将下载好的文件复制到一个临时目录,目的是为了不影响文件下载程序的执行。如果直接在文件下载目录操作就会出现一些逻辑上的问题,譬如对下载好的文件重命名后,下载程序检查源文件不存在就又会去下载,造成资源的浪费。
需要自己创建这个临时目录,如果这个目录已存在,就不需要去进行后续操作,证明该脚本已经执行过了。
创建好目录后将目标文件拷贝进来,然后遍历这个临时目录,对数据文件中的分割符进行替换,并查看数据文件有多少行记录,数据行数记录到一个新的校验文件中。
对文件进行重命名,并生成处理完成的标识文件。
最后将临时空间的文件全部移动至下载目录,注意移动顺序要先移动数据文件,在移动校验文件,最后移动标识文件。
脚本代码
#!/bin/env bash
export date=$1
export workpath=/home/tomcat/file/target/download/$date
function log(){
echo $1 >> /home/tomcat/file/target/download/log.txt
}
function copyfile(){
for fileName in `ls $1`
do
if [ -f $fileName ]
then
log "复制"$fileName"文件到rate_tmp目录"
cp $fileName ./rate_tmp
fi
done
}
#重命名
function renamefile(){
cd rate_tmp
for fileName in `ls $1`
do
if [ $fileName = "XXX.data" ]
then
log "将$fileName文件重命名为06_XXX_"$date"_XXX_000001.dat"
mv $fileName "06_XXX_"$date"_XXX_000001.dat"
elif [ $fileName = "XXX.ok" ]
then
log "将$fileName文件重命名为06_XXX_"$date"_XXX_000001.ok"
mv $fileName "06_XXX_"$date"_XXX_000001.ok"
elif [ $fileName = "XXX.data" ]
then
log "将$fileName文件重命名为06_XXX_"$date"_XXX_000001.dat"
mv $fileName "06_XXX_"$date"_XXX_000001.dat"
elif [ $fileName = "XXX.ok" ]
then
log "将$fileName文件重命名为06_XXX_"$date"_XXX_000001.ok"
mv $fileName "06_XXX_"$date"_XXX_000001.ok"
fi
done
}
export splitChar=\\x7C
export replaceChar=\\x03
#将换行符0D替换成空
export lineChar=\\x0D
export replaceLine=
#替换分割符 以及换行符 并生成chk文件
function replaceAndGenerate(){
for fileName in `ls $1`
do
if [ "${fileName##*.}" = "dat" ]
then
log "将"$fileName"文件中的分割符x7C替换为x03,换行符x0D替换为空,并生成chk文件"
sed -i "s/"$splitChar"/"$replaceChar"/g" $fileName
sed -i "s/"$lineChar"/"$replaceLine"/g" $fileName
echo `cat $fileName | wc -l`> "${fileName%.*}.chk"
fi
done
}
#将文件move 至上级目录 先移动dat 再移动chk 最后移动ok
function moveFileDat(){
for fileName in `ls $1`
do
if [ "${fileName##*.}" = "dat" ]
then
log "将"$fileName"文件移动至上级目录-"$date
mv $fileName '../'
fi
done
}
function moveFileChk(){
for fileName in `ls $1`
do
if [ "${fileName##*.}" = "chk" ]
then
log "将"$fileName"文件移动至上级目录:"$date
mv $fileName '../'
fi
done
}
function moveFileOk(){
for fileName in `ls $1`
do
if [ "${fileName##*.}" = "ok" ]
then
log "将"$fileName"文件移动至上级目录:"$date
mv $fileName '../'
fi
done
}
#先校验 参数目录是否存在
if [ ! -d $workpath ]
then
log "参数目录不存在,请检查是否存在该目录"$workpath
else
cd $workpath
if [ ! -d ./rate_tmp ]
then
log "创建rate_tmp目录"
mkdir rate_tmp
copyfile
renamefile
replaceAndGenerate
moveFileDat
moveFileChk
moveFileOk
else
log "rate_tmp目录已存在,不需要操作"
fi
fi
脚本放置目录如下
执行脚本
./guojie.sh 20210419
目录结构