目录
旧文贴上来,只是为了增加显示一个shell分类。
概述:
一般log文件处理,会遇到匹配字符串、对字符串某一部分截取、做计算处理等问题,这篇文章以一个应用实例,来:
代码目标:
匹配log文本中的指定字符串,如“111111111111111111111111”,然后比对相邻的匹配字符串的行开头的时间戳,若时间间隔超出阈值,则打印当前行。
|21:07:45:487| - actual sleep time=16572(ms)
|21:07:45:512| -
|21:07:45:512| - 111111111111111111111111111111111111111111111111111111111111111
|21:07:45:527| -
|21:07:45:527| -
|21:07:47:245| -
|21:07:47:245| - actual sleep time=1746(ms)
|21:07:47:324| -
|21:07:47:324| -
|21:07:50:712| -
|21:07:50:712| - actual sleep time=3453(ms)
|21:07:50:712| -
|21:07:50:715| - 222222222222222222222222222222222222222222222222222222222222222
|21:07:50:780| -
|21:07:50:780| -
|21:07:58:712| -
|21:07:58:713| - actual sleep time=8108(ms)
|21:07:58:744| -
|21:07:58:744| -
|21:08:03:529| -
|21:08:03:529| - actual sleep time=4882(ms)
|21:08:03:529| -
|21:08:03:532| - 111111111111111111111111111111111111111111111111111111111111111
|21:08:03:532| -
|21:08:03:532| -
|21:08:04:842| -
|21:08:04:843| - actual sleep time=1171(ms)
Ubuntu 16.04.2, GNU bash, version 4.3.48(1)-release-(x86_64-pc-linux-gnu)
MINGW32, GNU bash, version 3.1.23<1>-release <i686-pc-msys>
shell 应该属于宏语言,顾名思义是系统的壳,方便与系统交互的在以下情况下,不使用shell,因为shell对此无能为力;如:跨平台,较复杂数学操作(如浮点运算,精确运算等),图形化界面 GUI,I/O 或socket 接口,多维数组,对效率要求很高等。
如果使用python去写脚本来处理日常事务的话,相对于shell是一件比较麻烦的事情,因为我可以使用shell在花费更少的时间内,比较熟练地使用awk、sed和grep这些常用的命令在非常简短的脚本语句内,完成python一大段代码所能够完成的功能。
当然,上述讲述,仅针对python和shell做过一些底层驱动和字符文本处理,在其他应用场合两者的对比,不在本文讨论范围内。
Linux Shell 进制错误 - value too great for base
Shell 编程进行数学运算时,如果有字符 ‘0’ 打头的数 Bash 会当做八进制解释。解决办法是在变量或数字前加前缀“10#”,例如附录代码的compare_time()的处理
Linux Shell中的特殊符号和含义简明总结(包含了绝大部份)
https://www.jb51.net/article/51342.htm
NULL
NULL
正则表达式是包含在 两个斜杠之间 的一个或多个字符,在后一个斜杠的后面,可以指定一个或多个选项。
var regExp = /pattern/flags
其中,“pattern”为指定的匹配模式,flags为 0个 或多个可选项,这些选项及其含义如下:
• i:表示忽略大小写,就是在字符串匹配的时候不区分大小写。
• g:表示全局匹配,即匹配字符串中出现的所有模式。
• m:表示进行多行匹配。
题目中的合法表达式。
再举一些合法表达式的例子
var regExp1 = /abc/;
var regExp2 = /abc/gi;
var regExp3 = /^JavaScript/;
var regExp4 = /0[0-9][0-9]*/;
var regExp5 = /\binter/i;
http://www.regexper.com
Awk同shell一样,是一门脚本语言,有自己的语法和词汇
zoer@ubuntu:~$ touch a
zoer@ubuntu:~$ touch b
zoer@ubuntu:~$ cat a.txt
a
b
zoer@ubuntu:~$ awk '{cmd="rm "$0;system(cmd)}' a.txt
zoer@ubuntu:~$ ls
a.txt dd important mysql py testdata
daemon.py Desktop installer mysql_install_db.sh stu
data dfadsfadfadf jdk1.6.0_33 Public stu.txt
zoer@ubuntu:~$
我们在awk中组装命令并且最后使用system()来执行。每次读入一个文件名并删除这个文件。
下面我们使用awk中执行命令来创建一些文件。
1. zoer@ubuntu:~$ awk 'BEGIN{count=10;i=0;while(i
2. zoer@ubuntu:~$ ls
3. 0.txt 4.txt 8.txt dd jdk1.6.0_33 py
4. 1.txt 5.txt 9.txt Desktop mysql stu
5. 2.txt 6.txt daemon.py important mysql_install_db.sh stu.txt
6. 3.txt 7.txt data installer Public testdata
先把文件列表存在filename文件中
先
awk '{system("rm $0")}' filename -------WRONG
因为对于 system来说 $0 不再是某行全部的内容,而是 “sh” , 上面的命令相当于执行“ sh rm sh”
然后
awk '{cmd="rm "$0;system(cmd)}' filename ----OK
下面的也ok
awk '{cmd="rm "$0;cmd|getline }' filename ---- OK
man awk里面关于getline的说明,大意是说 运行command,同时会把输出存在$0 里面,或参数var中。
command | getline [var]
Run command piping the output either into $0 or var, as above.
command |& getline [var]
Run command as a co-process piping the output either into $0 or var, as above.
Co-processes are a gawk extension.
function add1()
{
result=`expr $1 + 1`
echo $result
}
export -f add1
awk 'BEGIN{p=3;"add1 "p|getline result;print result }'
function add1()
{
result=`expr $1 + $2 + 1`
echo $result
}
export -f add1
awk 'BEGIN{p=3;q=4;"add1 "p" "q|getline result;print result }'
function add1()
{
result=`expr $1 + 1`
exit $result
}
export -f add1
awk 'BEGIN{p=3;result=system("add1 "p);print result}'
#!/bin/bash
if [ $# -ne 2 ];
then
echo "Usage: $0 filename match_str";
exit -1
fi
filename=$1
match_str=$1
bash_version() {
local cmd="bash"
if command -v "$cmd" 2>&1 >/dev/null; then
ver=$("$cmd" --version | head -n 1)
else
ver="missing"
fi
printf "%s" "$ver"
}
function compare_time()
{
# printf "%s\n" $1
# printf "%s\n" $2
#分割操作不能直接使用参数全局变量,所以定义临时变量赋值
local aa=$1
local bb=$2
local hour1=${aa:0:2}
local minute1=${aa:3:2}
local second1=${aa:6:2}
local hour2=${bb:0:2}
local minute2=${bb:3:2}
local second2=${bb:6:2}
local dif=$[ $[ 10#$hour2*3600 + 10#$minute2*60 + 10#$second2 ] - $[ 10#$hour1*3600 + 10#$minute1*60 + 10#$second1 ] ]
if [ $dif -ge 7 ]; then
echo 1
return 1
else
echo 0
return 0
fi
}
printf "%s\n" "----------------------------"
printf "%20s: %s\n" "bash" "$(bash_version)"
#使用shell函数版
export -f compare_time
awk 'BEGIN{ print "Start"; last_time = 0; now_time = 0;}
{
if(match($0, /(APP_Test1Timer EXPIRED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)/))
{
now_time = substr($0, 2, 8)
# print last_time
# print now_time
# awk里的system只是获取函数或命令的退出状态值,范围0-255,如果return不在此范围会有问题
# ddd=system("compare_time "last_time" "now_time)
# 获取函数的echo返回值,只能使用getline方式
"compare_time "last_time" "now_time|getline ddd
if(ddd > 0)
{
print;
}
else
{
}
last_time = now_time;
}
else
{
}
}
END{ print "End" }' \
$filename
#仅使用awk程序版
awk 'BEGIN{ print "Start"; last_time = 0; now_time = 0;}
{
if(match($0, /(APP_Test1Timer EXPIRED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)/))
# if(match($0, /(111111111111111111111111111111111111111111111111111111111111111)/))
# if(match($0, /(222222222222222222222222222222222222222222222222222222222222222)/))
{
hour = substr($0, 2, 2)
minute = substr($0, 5, 2)
second = substr($0, 8, 2)
now_time = hour*3600 + minute * 60 + second
# print last_time
# print now_time
if((now_time - last_time) > 6)
{
print;
}
else
{
}
last_time = now_time;
}
else
{
}
}
END{ print "End" }' \
$filename
printf "%s\n" "----------------------------"
exit 0