一、需求
- 有一个日志文件
/www/test/test.log
- 我们需要把该日志文件
今天以前的日志
,按天拆分
到不同的文件中
。 - 拆分的文件位于
/www/test/split
文件夹,文件格式为test-Y-m-d.log
文件内容如下:
127.0.0.1 - - [24/Apr/2020:10:32:26 +0800] "详细日志信息1"
127.0.0.1 - - [24/Apr/2020:10:32:26 +0800] "详细日志信息2"
127.0.0.1 - - [27/Apr/2020:10:32:26 +0800] "详细日志信息3"
127.0.0.1 - - [21/Aug/2020:10:32:26 +0800] "详细日志信息4"
127.0.0.1 - - [24/Sep/2020:10:32:26 +0800] "详细日志信息5"
127.0.0.1 - - [25/Sep/2020:10:32:26 +0800] "详细日志信息6"
127.0.0.1 - - [15/Oct/2020:10:32:26 +0800] "详细日志信息7"
二、分析
- 我们暂时把脚本放在
/www/test
下,命名为test.bash
- 我们需要
递归创建文件夹
、创建文件
、把英文的月份转为数字
三个方法 逐行读取文件
,分析每一行的内容,满足条件就把该行信息写进对应的文件
三、代码
代码注释很详细,简单易读
#!/bin/bash
#文件夹不存在,则创建,参数从$1开始
createFolder(){
if [ ! -d $1 ]; then
mkdir -p $1 #创建文件夹: -p 递归创建文件夹
chmod -R 777 $1 # -R 递归给文件夹最大权限0777
fi
}
#文件不存在,则创建,参数从$1开始
createFile(){
if [ ! -f $1 ]; then
touch $1 #创建文件
chmod -R 777 $1 # -R 递归给文件最大权限0777
fi
}
#把英文的月份转为数字
monthToNumber(){
case $1 in
"Jan")
echo "01"
;;
"Feb")
echo "02"
;;
"Mar")
echo "03"
;;
"Apr")
echo "04"
;;
"May")
echo "05"
;;
"Jun")
echo "06"
;;
"Jul")
echo "07"
;;
"Aug")
echo "08"
;;
"Sep")
echo "09"
;;
"Oct")
echo "10"
;;
"Nov")
echo "11"
;;
"Dec")
echo "12"
;;
*)
echo "00" #default选项:异常月份,返回00
;;
esac
return $? #返回结果
}
rootFolder=/www/test/split #定义日志拆分文件夹根目录
todayDay=$(date -d "now" +%Y-%m-%d) #获取当前日期:年月
#:<<EOF 多行注释START
#逐行读取文件中的内容
cat /www/test/test.log | while read line
do
#正则匹配字符串: [24/Apr/2020:10:32:26 +0800]
# grep -o : 只输出符合 RE 的字符串. (gnu 新版独有, 不见得所有版本都支持.)
logTime=`echo $line|grep -o '\[[0-9]\{2\}\/[A-Za-z]\{1,\}\/[0-9]\{4\}:[0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\s\{1\}+[0-9]\{4\}\]'` #日志记录的时间
if [ ! -n "$logTime" ]; then
continue #匹配失败,进入下一个循环,读取下一行数据
fi
#根据正则匹配出的$logTime,截取出年月日
year=`echo ${
logTime:8:4}` #字符串截取 年
monthEnglish=`echo ${
logTime:4:3}` #字符串截取 月
month=$(monthToNumber $monthEnglish) # 英文月份转为数字
day=`echo ${
logTime:1:2}` #字符串截取 日
touchFile=test-$year-$month-$day.log #test-2020-04-04.log 拆分的文件名定义
splitFile=$rootFolder/$touchFile #拼接日志存放的位置
#如果是今天的日志,则不记录
todayFile=$splitFolder/test-$todayDay.log #定义今天的日志文件名
if [ "$splitFile" = "$todayFile" ]; then
#echo $todayFile
break #已经读到了今天的日志了,不记录,直接跳出循环
fi
createFolder $rootFolder #文件夹不存在时,创建文件夹
createFile $splitFile #文件不存在时,创建文件
echo $line>>$splitFile # 文件内容追加
#exit 0 #程序退出操作
done
#EOF 多行注释END
四、运行
cd /www/test
sh test.bash
如果报错:Shell 脚本执行错误 $‘\r‘:command not found
五、执行结果
图片
文件 test-2020-04-24.log 内容
127.0.0.1 - - [24/Apr/2020:10:32:26 +0800] "详细日志信息1"
127.0.0.1 - - [24/Apr/2020:10:32:26 +0800] "详细日志信息2"
文件 test-2020-09-25.log 内容
127.0.0.1 - - [25/Sep/2020:10:32:26 +0800] "详细日志信息6"
六、其他
- 注意,赋值号
=
的周围不能有空格,这可能和你熟悉的大部分编程语言都不一样。 - Shell变量:Shell变量的定义、赋值和删除
- Shell字符串拼接(连接、合并)
Shell 字符串拼接案例
- 代码
#!/bin/bash
name="Shell"
url="http://c.biancheng.net/shell/"
str1=$name$url #中间不能有空格
str2="$name $url" #如果被双引号包围,那么中间可以有空格
str3=$name": "$url #中间可以出现别的字符串
str4="$name: $url" #这样写也可以
str5="${name}Script: ${url}index.html" #这个时候需要给变量名加上大括号
echo $str1
echo $str2
echo $str3
echo $str4
echo $str5
- 运行结果
Shellhttp://c.biancheng.net/shell/
Shell http://c.biancheng.net/shell/
Shell: http://c.biancheng.net/shell/
Shell: http://c.biancheng.net/shell/
ShellScript: http://c.biancheng.net/shell/index.html