前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux命令三剑客的一顿操作

Linux命令三剑客的一顿操作

作者头像
AsiaYe
发布2019-11-06 17:07:07
4390
发布2019-11-06 17:07:07
举报
文章被收录于专栏:DBA随笔

Linux命令三剑客的一顿操作

今天在写一个脚本的时候,遇到了很多字符过滤的问题,感觉还是有些技术含量的,这里记录下来,以便后续参阅。

我们都知道Linux常用命令有很多,我们把grep、sed和awk称之为Linux命令的"三剑客",能叫三剑客,必有过人之处,这三个命令加起来,可以实现很多我们想要的功能,在文本处理领域简直是上天入地,无所不能。三剑客,顾名思义,就是三个剑客,像下面这样:

你可以把他理解成海、陆、空,亦或天、地、人,也可以理解为剑圣、剑魔、剑贪,算了,编不下去了,开始正题吧,哈哈哈~(有点儿像沙雕网友)

01

问题描述

实际上我是在处理这样一个问题:在mysql的一个binlog日志文件中,找到从库的复制偏移量,也就是master_binlog_num和master_binlog_pos,找到了这两个值之后,需要确定这个master_binlog_pos生成的时间是什么时候。

上面的描述可能不是特别清楚,我们先看下一个binlog里面的内容吧:

代码语言:javascript
复制
# at 181
#190428 11:47:54 server id 10226  end_log_pos 180578    Query   thread_id=4631538       exec_time=0     error_code=0
use shop_gp/*!*/;
SET TIMESTAMP=1556423274/*!*/;
SET @@session.time_zone='SYSTEM'/*!*/;

如上所述,位置181的生成时间就是10年04月28日,11点47分54秒,要实现这个目标,我们需要把这个at 181下面的一行数据找到,然后进行文本过滤,最后生成我们想要的目标:2019-04-28 11:47:54。

那么具体怎么做呢,来看实际操作。

02

实际操作

1.找到181所在的位置:

代码语言:javascript
复制
[root innodblog]# mysqlbinlog mysqlbin.013613|grep '# at 181'
# at 181

上面这个结果比较好找,我们直接使用mysqlbinlog来查看这个二进制日志文件即可,然后再后面通过grep来过滤出来我们想要的位置,如上述代码所示。

2.当我们找到这个固定位置之后,需要找到这个位置的下一行,这里我们可以使用grep里面的-A参数,关于-A参数,我们简单进行说明:

grep -A n

A是after的意思,显示过滤到的行数,后面可以跟数字,除了显示符合范本样式的那一列之外,并显示该行之后n行的内容。

来看示例:

代码语言:javascript
复制
[root innodblog]# mysqlbinlog mysqlbin.013613|grep -A 1 '# at 181' 
# at 181
#190428 11:47:54 server id 10226  end_log_pos 180578    Query   thread_id=4631538       exec_time=0     error_code=0

[root innodblog]# mysqlbinlog mysqlbin.013613|grep -A 2 '# at 181' 
# at 181
#190428 11:47:54 server id 10226  end_log_pos 180578    Query   thread_id=4631538       exec_time=0     error_code=0
use shop_gp/*!*/;

[root innodblog]# mysqlbinlog mysqlbin.013613|grep -A 3 '# at 181' 
#190428 11:47:54 server id 10226  end_log_pos 180578    Query   thread_id=4631538       exec_time=0     error_code=0
use jj_shop_gp/*!*/;
SET TIMESTAMP=1556423274/*!*/;

这里多说一句,-B参数是before的意思,和-A操作差不多,大家可以试一下。

3.我们使用grep -A 1的方法取到下一行的值,当我们拿到这个值的时候,接下来要做一个tail的操作,这个tail的作用是指获取带有时间的那一行值,而把我们过滤用的at 181那一行去除掉:

代码语言:javascript
复制
[root innodblog]# mysqlbinlog mysqlbin.013613|grep -A 1 '# at 181'|tail -1
#190428 11:47:54 server id 10226  end_log_pos 180578    Query   thread_id=4631538       exec_time=0     error_code=0

这样,我们就拿到了含有时间的那一行值,对这行值我们需要再次进行过滤。

4.这里,awk命令就派上用场了,关于这个awk命令,之前的文章里面有讲过,这里我们不在进行赘述,有兴趣的同学可以翻看前面的文章,我们使用awk命令,以server id为分割条件,将语句进行分割,然后取前半部分,写出来就是:

代码语言:javascript
复制
[root@tk-dba-dr-mysql226 innodblog]# mysqlbinlog mysqlbin.013613|grep -A 1 '# at 181'|
tail -1|awk -F'server id' '{print $1}' 
#190428 11:47:54 

可以看到,第3行的结果已经距离我们的目标很接近了。

5.现在我们的结果是#190428 11:47:54 ,我们想要的结果是:2019-04-28 11:47:54,首先我们需要将#换成20,也就是将结果转化成20190428 11:47:54,操作如下:

代码语言:javascript
复制
[root innodblog]# mysqlbinlog mysqlbin.013613|grep -A 1 '# at 181'
|tail -1|awk -F'server id' '{print $1}'|sed s/^#/20/g
20190428 11:47:54 

说说最后的sed命令,这个sed命令用来替换行,它的语法是sed s/原来的字符串/替换后的字符串/g

我们使用的是 sed s/^#/20/g,其中,^代表匹配开头,^#指的是以^#开头的字符串,将^#转换成20,其中g的意思是替换的意思。

这样就替换成了20190428 11:47:54

6.现在就剩最后一步了,也就是转化成时间格式,这里我们使用linux中的date命令:

代码语言:javascript
复制
[root innodblog]# date +"%Y-%m-%d %H:%M:%S" -d "20190428  1:47:17"
2019-04-28 01:47:17

至此,目标达成。

03

再来一例

上面的例子是处理一个master_binlog_pos发生的时间,接下来这个例子是在xtrabackup备份的过程中,在众多信息中过滤出master_binlog_pos,废话就不过说了,我们先来看看xtrabackup备份时候打印出来的日志,如下:

代码语言:javascript
复制
xtrabackup: Creating suspend file '/tmp/xtrabackup_log_copied' with pid '42480'
xtrabackup: Transaction log of lsn (4774004270781) to (4774008985300) was copied.
190428 00:18:15  innobackupex: All tables unlocked

innobackupex: Backup created in directory '/root'
innobackupex: MySQL binlog position: filename 'mysqlbin.000002', position 65330751
190428 00:18:15  innobackupex: Connection to database server closed
innobackupex: You must use -i (--ignore-zeros) option for extraction of the tar stream.
190428 00:18:15  innobackupex: completed OK!

我们需要在日志中,把第6行中的position过滤出来,也就是要过滤出来数字:65330751

具体的操作步骤如下:

1.首先需要定位到这一行日志,我们采用的方法依旧是grep,如下:

代码语言:javascript
复制
[dba_mysql tmp]$ grep 'MySQL binlog position:' xtra.log 
innobackupex: MySQL binlog position: filename 'mysqlbin.000002', position 65330751

我们首先通过grep命令拿到目标行。

2.紧接着我们对这个命令行中的内容进行过滤,这里我们采用awk作为过滤方法,使用的命令如下:

代码语言:javascript
复制
[dba_mysql@tk-dba-mysql-194 tmp]$ grep 'MySQL binlog position:' xtra.log 
| awk '{b=index($0,", position ");print substr($0,b+10)}'
 65330751

可以看到,我们使用index函数作为过滤的条件,index函数的作用是在字符串中找到指定子串的位置,然后返回位置,如果指定的字串不存在,那么返回0.我们使用index返回", position"这个字符串所在的位置,把它的位置标记为变量b。然后我们使用了一个substr的函数,这个函数的用法如下:

substr(String,M,(N)) 其中,N为可选。

返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。

它的作用是打印出变量b加10个字符的位置到字符串末尾的字符,也就是" 65330751",这里需要注意,这个数字前面有一个空格,想去掉这个空格,其实很简单,就是把b+10改为b+11即可,下面给出不同的位置处处理的结果:

代码语言:javascript
复制
[dba_mysql@tk-dba-mysql-194 tmp]$ grep 'MySQL binlog position:' xtra.log 
| awk '{b=index($0,", position ");print substr($0,b+10)}'
 65330751
[dba_mysql@tk-dba-mysql-194 tmp]$ grep 'MySQL binlog position:' xtra.log 
| awk '{b=index($0,", position ");print substr($0,b+11)}'
65330751
[dba_mysql@tk-dba-mysql-194 tmp]$ grep 'MySQL binlog position:' xtra.log 
| awk '{b=index($0,", position ");print substr($0,b+9)}'
n 65330751

,这里我们通过另外一种方法去掉空格。

3.上面的结果中包含一个空格,我们要是想继续用sed来去除这个空格,可以写成如下形式:

代码语言:javascript
复制
[dba_mysql@tk-dba-mysql-194 tmp]$ grep 'MySQL binlog position:' xtra.log 
| awk '{b=index($0,", position ");print substr($0,b+10)}'
| sed 's/^[ \t]*//g'
65330751

我们需要注意的是第3行,它使用了sed函数,格式为:

sed 's/^[ \t]//g'

它的意思是将每一行前导的“空白字符”(空格,制表符)删除。其中^的意思是行首,[ \t]指的是空格或者制表符。

当然,这个命令的实际操作其实我们可以使用更为简单的方法,这里我们为了给大家演示sed和grep以及awk命令,故意使用了一些不太"高效"的方法。关于这三个命令能处理的情况还有很多,后续有典型的可以继续给大家分享,今天就到这里吧。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档