利器 | 测试必会之 Linux 三剑客 ( grep / awk / sed )

Linux 给人的印象是黑乎乎的神秘窗口,文本操作和数据处理似乎没有 Windows 窗口界面直观方便。其实Linux 有自己的独特的法宝,称之为三剑客:grep,awk 和 sed。你可以用这三件法宝很方便的处理数据 :查找,分段,修改,而这三个功能对应着我们今天的主角:grep,awk,sed。

形象一点比喻,如果把数据比作人群,那么 grep 就是照妖镜,用来找出妖精;awk 就是尺子,给人群分门别类;而 sed 就是宝剑,用来除掉妖精。当你明白为什么要用三剑客时,就更容易拿这三把剑去斩妖除魔。

1. grep

grep-global regular expression print - 全局正则表达式打印
可用于数据查找定位

先列举出测试工作常用的grep命令和意义:

grep pattern file
grep -i pattern file 忽略大小写
grep -v pattern file  不显示匹配行
grep -o pattern file 只把每个匹配的内容独立的行显示
grep -E pattern file 使用拓展正则表达式
#注意:grep 'a[0-9]\{10\}' 等同于 grep -E 'a[0-9]{10}' 
grep -A -B -C pattern file 打印命中数据的上下文
grep pattern -r dir/ 递归搜索
grep -m1 匹配匹配中的第一个
grep -n 顺便输出行号

下面以一个检查首页是否有死链的案例需求来展示 grep 的匹配用法

以目前国内最大的测试社区网站 testerhome 为例,访问 testerhome 主页,找出主页中包含的左右 url,分别进行访问,如果访问成功会返回状态码200,检查所有访问成功的url并打印出来,若没访问成功就打印ERR加上失败的url。

1.先访问 Testerhome 社区主页,利用 grep href 过滤出所有包含 url 的内容。命令:

curl -s https://testerhome.com | grep href

图片

2.从返回的结果中取出 url,观察发现所有的 url 都被包在了双引号之中,那么在利用 grep -o 命令,加上正则表达式匹配,只打印从 http 开始到 url 结束双引号之前的内容。命令:

curl -s https://testerhome.com | grep href | grep -o "http[^\"]*"

在这里插入图片描述

3.从上一步中我们已经取出了完整的 url 了,现在我们需要对每个url进行访问取值判断

3.1. 先用curl -I 看看请求返回的头信息内容。命令:

curl -s -I https://testerhome.com/topics/feed

图片

3.2. 访问成功返回200,这时候我们一行一行去访问,再用grep命令匹配"200 OK"作为判断条件,筛选出成功的url并打印,然后将失败的 url 加上 ERR 标记也一起打印出来。命令

curl -s https://testerhome.com | grep href | grep -o "http[^\"]*" | while read line;do curl -s -I $line | grep 200 && echo $line || echo ERR $line;done

4.最终结果展示

图片

2. awk

awk = “Aho Weiberger and Kernighan” 三个作者的姓的第一个字母
awk 是 Linux 下的一个命令,同时也是一种语言解析引擎
awk 具备完整的编程特性。比如执行命令,网络请求等
精通 awk,是一个 Linux 工作者的必备技能
语法:awk ‘pattern{action}’

awk pattern语法

awk 理论上可以代替 grep

awk ‘pattern{action}’ ,默认以空格分隔

awk ‘BBEGIN{}END{}’ 开始和结束
awk ‘/Running/’ 正则匹配
awk ‘/aa/,/bb/’ 区间选择
awk ‘$2~/xxx/’ 字段匹配,这里指从第2个字段开始匹配包含xxx内容的行
awk ’NR==2’ 取第二行
awk ’NR>1’ 去掉第一行

awk的字段数据处理

-F 参数指定字段分隔符

BEGIN{FS=‘_’} 也可以表示分隔符

$0 代表原来的行
$1 代表第一个字段
$N 代表第N个字段
$NF 代表最后一个字段

下面以一个在nginx.log中查找返回状态码非200的请求响应数目的需求为例,演示awk的基础用法

有一份nginx.log文件,打开后内容格式如下:

220.181.108.111 - - [05/Dec/2018:00:11:42 +0000] "GET /topics/15225/show_wechat HTTP/1.1" 200 1684 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" 0.029 0.029 .
216.244.66.241 - - [05/Dec/2018:00:11:42 +0000] "GET /topics/10052/replies/85845/reply_suggest HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" 0.016 0.016 .
216.244.66.241 - - [05/Dec/2018:00:11:42 +0000] "GET /topics/10040?order_by=created_at HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" 0.002 0.002 .
216.244.66.241 - - [05/Dec/2018:00:11:42 +0000] "GET /topics/10043/replies/85544/reply_suggest HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" 0.001 0.001 .
216.244.66.241 - - [05/Dec/2018:00:11:44 +0000] "GET /topics/10075/replies/89029/edit HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" 0.001 0.001 .
216.244.66.241 - - [05/Dec/2018:00:11:44 +0000] "GET /topics/10075/replies/89631/edit HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" 0.001 0.001 .
216.244.66.241 - - [05/Dec/2018:00:11:45 +0000] "GET /topics/10075?order_by=created_at HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" 0.000 0.000 .
216.244.66.241 - - [05/Dec/2018:00:11:45 +0000] "GET /topics/10075?order_by=like HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" 0.001 0.001 .
223.71.41.98 - - [05/Dec/2018:00:11:46 +0000] "GET /cable HTTP/1.1" 101 60749 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0" 2608.898 2608.898 .
113.87.161.17 - - [05/Dec/2018:00:11:39 +0000] "GET /cable HTTP/1.1" 101 3038 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36" 112.418 112.418 .
216.244.66.241 - - [05/Dec/2018:00:11:46 +0000] "GET /topics/10079/replies/119591/edit HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" 0.001 0.001 .
216.244.66.241 - - [05/Dec/2018:00:11:46 +0000] "GET /topics/10089?locale=zh-TW HTTP/1.1" 301 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" 0.002 0.002 .

观察log内容,可以发现,以空格为分隔符,状态码在第九个字段位置;这里我们用awk命令从第九个字段位置开始匹配非200的状态码并打印出来。命令:

awk '$9!~/200/{print $9}' nginx.log
[avbxb9efockpz ~]$ awk '$9!~/200/{print $9}' nginx.log301
301
301
301
301
301
301
301
301
......#剩余部分省略

再对取出的数据进行排序->去重->按数字的倒叙进行排列。命令:

awk '$9!~/200/{print $9}' nginx.log | sort | uniq -c | sort -nr

命令含义:

sort: 按从小到大进行排序
uniq -c :去重(相邻)
-nr: 按数字进行倒叙排序
-n:按数字进行排序

结果展示:

[sqavbxb9efockpz ~]$ awk '$9!~/200/{print $9}' nginx.log | sort | uniq -c | sort -nr
    433 101
    304 301
    266 404
    152 302
      7 401
      5 304
      2 499
      2 422
      1 500

再结合 awk ‘BBEGIN{}END{}’ 命令,以统计当前用户数目的例子来展示命令用法

使用cat /etc/passwd命令来查看本机用户,我们需要提取出用户名称并加上数字序号显示出来,达到这种效果:

1 nobody2 root
3 daemon
4 _uucp
5 _taskgated
6 _networkd
7 _installassistant
8 _lp
9 _postfix
......

用户信息:

localhost:~ qinzhen$ cat /etc/passwd
##
# User Database
#
# Note that this file is consulted directly only when the system is running
# in single-user mode.  At other times this information is provided by
# Open Directory.
#
# See the opendirectoryd(8) man page for additional information about
# Open Directory.
##
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
_uucp:*:4:4:Unix to Unix Copy Protocol:/var/spool/uucp:/usr/sbin/uucico
_taskgated:*:13:13:Task Gate Daemon:/var/empty:/usr/bin/false
_networkd:*:24:24:Network Services:/var/networkd:/usr/bin/false
_installassistant:*:25:25:Install Assistant:/var/empty:/usr/bin/false
_lp:*:26:26:Printing Services:/var/spool/cups:/usr/bin/false
_postfix:*:27:27:Postfix Mail Server:/var/spool/postfix:/usr/bin/false
_scsd:*:31:31:Service Configuration Service:/var/empty:/usr/bin/false
_ces:*:32:32:Certificate Enrollment Service:/var/empty:/usr/bin/false
_appstore:*:33:33:Mac App Store Service:/var/empty:/usr/bin/false
_mcxalr:*:54:54:MCX AppLaunch:/var/empty:/usr/bin/false
......#后面的省略

思路:

* awk运行前先定义序号索引0,用来递增保存用户
* 利用awk将用户提取出来,按索引分别保存;
* 切片结束后再按行数进行循环,将数字序号与第一步保存的信息拼接打印
* 注意:cat /etc/passwd打印出的结果中,最上方的注释需要处理跳过
cat /etc/passwd | awk -F ':' 'BEGINE{userindex=0}{user[userindex]=$1;userindex++}END{for(i=0;i<NR;i++)print i+1, user[i+10]}' |less

在这里插入图片描述

3. sed

sed:stream editor 根据定位到的数据行修改数据

sed [-nefri] [动作]
参数:
-n :使用安静(slient)模式。只有经过sed特殊处理的那一行(或者操作)才会被列出来。一般与p配合使用
-e :直接在命令行模式上进行sed的动作编辑
-f :直接将sed动作写在一个文件内,-f filename则可以执行filename 内的sed动作。
-r :sed的动作支持的是拓展正则表达式的语法(默认是基础正则表达式的语法)
-i :直接修改读取的文件内容,而不是由屏幕输出
动作说明:[[n1][,n2]]function
n1,n2 :不见得会存在,一般代表选择进行动作的行数,举例来说,如果我的动作是需要在10到20之间进行的,则“10,20[动作行为]”

function有下面这些参数:
a :新增
d :删除 (比较重要,测试工作中对数据处理时可快速去除无用信息,比如注释行,空白行等)
i :插入
p :打印 (一般与-n配合使用)
s :替换(重中之重!!!,s参数可以说是日常测试工作中对数据用sed清理过滤时使用率最高的了)

sed 修改表达式:sed ‘s/待修改/修改结果/’

注意说明:

表达式单引号中的s表示修改,/ 符号表示分隔,实际上将/换成其他符号也可以,只要能起到分隔作用就OK

[16210504@izuf60jasqavbxb9efockpz ~]$ echo "aaa|bbb}|cccbbb" | sed 's/bbb/BBB/'
aaa|BBB}|cccbbb
[16210504@izuf60jasqavbxb9efockpz ~]$ echo "aaa|bbb}|cccbbb" | sed 's#bbb#BBB#'
aaa|BBB}|cccbbb

若想讲目标中所有的字段都替换,需要在命令最后加上g:

[16210504@izuf60jasqavbxb9efockpz ~]$ echo "aaa|bbb}|cccbbb" | sed 's/bbb/BBB/g'
aaa|BBB}|cccBBB

sed还可以修改文件中的内容,现在有文件text.txt,内容如下:

[16210504@izuf60jasqavbxb9efockpz ~]$ cat text.txt
hello bash world
hi~ tester
go go go go!

用sed ‘s/hello/HELLO/’ text.txt 命令将文件中的hello替换成HELLO:

[16210504@izuf60jasqavbxb9efockpz ~]$ sed 's/hello/HELLO/' text.txt
HELLO bash world
hi~ tester
go go go go!

但是此时我们打开源text.txt文件发下源文件内容并未改变:

[16210504@izuf60jasqavbxb9efockpz ~]$ cat text.txt
hello bash world
hi~ tester
go go go go!

注意说明:

sed 在修改文件内容时,是另外开辟了一块模式空间,将修改后的内容放入并输出,源文件并未修改;

这时如果想要修改源文件就需要借助-i命令,另外为了防止误操作修改文件,一般可以采取这种写法:sed -i.bak ‘s/hello/HELLO/’ text.txt,这种写法在修改源文件的同时还会生成一份以.bak结尾的备份文件,相较安全。

[16210504@izuf60jasqavbxb9efockpz ~]$ sed -i.bak 's/hello/HELLO/' text.txt
[16210504@izuf60jasqavbxb9efockpz ~]$ ls
1  1.sh  Allen_qin  nginx.log  test  text.txt  text.txt.bak  while_test
[16210504@izuf60jasqavbxb9efockpz ~]$ cat text.txt
HELLO bash world
hi~ tester
go go go go!
[16210504@izuf60jasqavbxb9efockpz ~]$ cat text.txt.bak
hello bash world
hi~ tester
go go go go!

sed -e命令可以直接在命令行模式上进行sed的动作编辑,但看解释比较晦涩,来看一个实例:

需求: 现有一个1.txt的文本,内容如下:

a:
b:
c:
d:

要将其中每行末尾的:都替换成@,将a替换成A,并在文本末尾加上“Sed Test”
命令:

sed -i -e 's/:/@/g' \
-i -e 's/a/A/' \
-i -e '$a Sed Test' 1.txt

实例演示:

[16210504@izuf60jasqavbxb9efockpz ~]$ sed -i -e 's/:/@/g' -i -e 's/a/A/' -i -e '$a Sed Test' 1.txt
[16210504@izuf60jasqavbxb9efockpz ~]$ cat 1.txt
A@
b@
c@
d@
Sed Test

行动吧,在路上总比一直观望的要好,未来的你肯定会感 谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入扣群: 320231853,里面有各种软件测试+开发资料和技术可以一起交流学习哦。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

  • 17
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux三剑客指的是 awksedgrepawk 是一种用来处理文本文件的工具,它可以根据指定的模式进行自动分割并进行数据处理。 sed 是一种流编辑器,它可以对文本文件进行替换、删除和插入操作。 grep 是一种文本搜索工具,它可以在文本文件中搜索指定的字符串。 ### 回答2: Linux三剑客,分别是awksedgrep,它们是Linux系统中非常重要的命令行工具,它们通常被称为文本处理工具。这些工具通常被用于筛选、搜索和处理文本文件。 grep是一种常见的文本搜索工具,可以在文件和文件夹中搜索指定的字符串或正则表达式。grep可以搜索多个文件并返回匹配行的输出。它是处理日志文件或查找匹配模式的最佳工具之一。 sed是一种流编辑器,可以按照行处理文本文件。它可以通过替换、删除和插入操作来修改文件内容。在大型文件中查找并替换模式是sed的主要作用。该工具通常在文本文件中提取有用信息是常用。 awk是一种强大的文本操作工具,可以分析大型文本文件并对其进行处理。该工具可以遍历行和列,并提供强大的文本处理工具,如计算、过滤和转换数据。awk的处理速度非常快,适用于处理大型数据文件。 Linux三剑客awk是最强大的工具,它可以执行复杂的文本数据操作和转换,可大大简化开发和管理过程。sed主要用于简单的文本数据过滤和替换,而grep主要用于搜索文件和定位特定行。 总之,Linux三剑客在文本数据处理方面具有不可替代的重要作用。对于Linux操作系统的开发人员和管理员来说,熟练使用这些工具可以提高他们的工作效率,使他们更容易管理和操作文本文件。 ### 回答3: Linux三剑客awk sed grep是我们在日常工作中经常使用的三个命令。它们都属于文本处理工具,可以用于查找、处理、分析文本文件等。 首先,grep是最常用的文本搜索工具。grep可以用来快速查找文件中指定的字符串或正则表达式,并将包含该字符串或正则表达式的行打印出来。常用的命令有grep、egrep和fgrep。比如,我们可以使用grep命令来查找一个文件中包含指定关键字的行,可以使用egrep来支持正则表达式搜索,使用fgrep来进行快速搜索,不支持正则表达式。 其次,sed是一种流编辑器,主要用于对文本文件进行替换、删除、添加、插入等操作。sed命令可以通过管道(|)将多个命令组合起来,从而进行复杂的文本操作。sed可以快速完成对文本文件的修改操作,比如替换文件中的某些内容、删除特定的行、在文件中插入新的文本等。sed的命令形式是“command", 比如"s/old/new/g",表示将old替换成new。 最后,awk是一种强大的文本处理工具,主要用于在文本文件中查找、处理以及格式化特定的字段。和grepsed不同的是,awk更加灵活,可以在处理过程中做到数据过滤和加工,对于大数据的处理特别有用。awk命令的常用语法是"pattern {action}"。其中,pattern代表要匹配的模式,而action代表模式匹配时需要执行的动作,我们可以在其中添加处理语句来对文件进行各种处理操作,比如计算、统计、格式化等。 综上所述,Linux三剑客awk sed grep是我们在文本处理工作中不可或缺的三个工具,不同的工具可以用于处理不同的文本操作,也可以用于搭配使用,以完成更加复杂的文本处理工作。对于需要经常处理文本的人员来说,掌握这些工具是非常必要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值