Linux三剑客grep、sed、awk

发布于 2020-12-21  1,953 次阅读


Linux中最重要的三个命令在业界被称为“三剑客”,它们是awk,sed,grep。

我们现在知道Linux下一切皆文件,对Linux的操作就是对文件的处理,那么怎么能更好的处理文件呢?这就要用到我们上面的三剑客命令

  • grep 搜索过滤
  • sed 文件行操作
  • awk 文件列操作

grep,sed,awk操作都离不开正则表达式

正则表达式

元字符功能意思
^匹配行首表示以某个字符开头
$匹配行尾表示以某个字符结尾
^$空行表示开头结尾都是空
.匹配任意一个单字符匹配任意单个字符
*匹配0个或者多个字符表示重复的任意多个字
\屏蔽一个元字符的特殊含义转义
[]匹配中括号内的内容过滤括号内的字符
.*匹配任意多个字符匹配所有

1.grep

Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户

格式
grep [options]

主要参数
[options]主要参数:

--color=auto 对匹配到的文本着色显示
-v 显示不被pattern匹配到的行
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串
-q 静默模式,不输出任何信息
-A # after, 后#行
-B # before, 前#行
-C # context, 前后各#行
-e 实现多个选项间的逻辑or关系
grep –e ‘cat ’ -e ‘dog’ file
-w 匹配整个单词
-E 使用ERE,相当于egrep
-F 相当于fgrep,不支持正则表达式

eg:

ps -ef|grep python|grep -v grep #配合管道使用,表示查看当前python进程,并排除掉grep命令自身

grep命令是Linux命令中使用非常高频的一个命令,几乎是天天用到

2.sed

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’ 的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

sed命令格式

sed [-nefr] [动作]

选项与参数:
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来(不输出模式空间内容到屏幕,即不自动打印)。
-e :直接在命令列模式上进行 sed 的动作编辑(多点编辑); 
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作(从指定文件中读取编辑脚本);
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端(直接编辑文件,危险动作)
-i.bak: 备份文件并原处编辑
sed 'root' /etc/passwd  # 遍历passwd每行匹配root,会打印原行
sed -n 'root' /etc/passwd # 同上,不会打印原行
sed -n '/root/p' /etc/passwd # 正则每行匹配root,匹配成功则打印

正则匹配

sed -n -r '/chenshiyang|CHENSHIYANG/p' test.txt

直接修改内容

sed -i 's@chenshiyang@chenshiyang1@g' test.txt

sed 动作说明:[n1, [n2]] function

n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』

function: 
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行) 
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚; 
c :替换行为单行或多行文本
= :为模式空间中的行打印行号
i :插入i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
! :模式空间中匹配行取反处理
s :查找替换,支持使用其它分隔符,s@@@,s###
    替换标记:
        g 行内全局替换
        p 显示替换成功的行
        w /PATH/TO/SOMEFILE 将替换成功的行保存至文件中

10command                         //匹配到第10行

10, 20command                     //匹配从第10行开始,到第20行结束

10,+5command                     //匹配从第10行开始,到第15行结束,打印第10行后在再打印5行

/pattern1/command                 //匹配到pattern1的行(满足pattern1条件的行)

/pattern1/,/pattern2/command     //匹配到pattern1的行开始,到匹配到pattern2的行结束10,

/pattern1/command             //匹配从第10行开始,到匹配到pettern1的行结束

/pattern1/, 10command             //匹配到pattern1的行开始,到第10行匹配结束

使用示例

sed-n "10p"/etc/passwd

sed-n "3,10p"/etc/passwd

sed-n "3,+2p"/etc/passwd

sed-n "/usbmux/p"/etc/passwd

sed-n "/^usbmux/,/^whoopsie/p"/etc/passwd

sed-n "6,/usbmux/p"/etc/passwd

sed-n "/usbmux/,9p"/etc/passwd

sed引用变量的注意事项:

  • 当匹配模式中存在变量,则建议使用双引号
  • sed中需要引入自定义变量时,如果外面使用单引号,则自定义变量也必须使用单引号

eg:

p模式

  1. cat test.txt -n | sed 5p # 编辑第五行,并在屏幕中显示
  2. cat test.txt -n | sed -n 4p # 只显示第五行
  3. cat test.txt -n | sed -n 3,6p # 显示3-5行内容
  4. cat text.txt -n | sed -n '3p;6p' # 显示第三行和第五行
  5. sed -n '/#/p' test.txt # 显示包含#的行
  6. sed -n '/#/!p' test.txt # 显示不包含#的行
  7. sed -n '/\:/p' test.txt # 显示包含:的行
  8. sed -n '/^chen/p' test.txt # 显示以chen开头的行
  9. sed -n '/^$/!p' test.txt # 不显示空行
  10. sed -n '/^$/!p' test.txt | sed -n '/^#/!p' # 不显示空行和包含#的行

d模式

  1. sed '/^chen/d' test.txt # 删除chen所在行
  2. sed '/^chen/!d' test.txt # 除chen行,其他都删除
  3. sed '/^#/d' test.txt # 删除所有含#的行
  4. sed '/^$/d' test.txt # 删除空格行
  5. cat -n test.txt | sed '5d' # 删除第五行
  6. cat -n test.txt | sed '2d;5d' # 删除第二行和第五行
  7. cat -n test.txt | sed '2,5d' # 删除2-5行

a模式

  1. sed '/^chen/ahello'test.txt # 在包含chen的下一行添加hello
  2. sed '/^chen/ahello\nworld' test.txt # 在chen下一行添加hello, world两行
  3. sed '4ahello\nworld' test.txt # 在第四行的下一行添加 hello,world两行
  4. sed '4ihello\nworld' test.txt # 在第四行插入hello,world两行

c模式

  1. sed '/#/chello' test.txt # 将所有含#的行改为hello
  2. sed -i '/^#/cchenshiyang' test.txt # 将所有含#的行给为chenshiyang并保存修改

其他用法

  • sed -n '/^chen/=' test.txt # 包含内容在文件中的行号
  • sed -n '$=' test.txt # 统计行数

3.awk

awk是一个文本处理工具,通常用于处理数据并生成结果报告

语法格式:

        awk 'BEGIN{}pattern{commands}END{}' file_name

        standard output | awk 'BEGIN{}pattern{commands}END{}'

        BEGIN{}:正式处理数据之前执行,固定写法

        parttern:匹配模式

        {commands}:处理命令,可能多行

        END{}:处理完所有匹配数据后执行,固定写法

awk的内置变量:

  • $0          //整行内容
  • $1-$n     //当前行的第1-n个字段(相当于用分隔符分割后的元素)
  • NF         //当前行的字段个数,也就是有多少列 (Number Field)
  • NR         //当前行的行号,从1开始计数 (Number Row)
  • FNR      //多文件处理时,每个文件行号单独计数,都是从0开始(File Number Row)
  • FS        //输入字段分隔符。不指定默认以空格或tab键分割(Field Separator)
  • RS        //输入行分隔符。默认回车换行 (Row Separator)
  • OFS     //输出字段分隔符。默认为空格(output Field Separator)
  • ORS     //输出行分隔符。默认为回车换行  (output Row Separator)    
  • FILENAME //处理文件的文件名    
  • ARGC     //命令行参数个数
  • ARGV    //命令行参数数组

eg:

awk'{print $0}' /etc/passwd     //输出test.txt的每一行内容awk'BEGIN{FS=":"}{print $1}' /etc/passwd //以':'分割每行内容,输出每一行的第一个字段,这里第一行会输出'root'

awk'BEGIN{FS=":"}{print NF}' /etc/passwd //输出每一行字段个数,第一行有7个字段

awk模式匹配的两种用法:

        第一种匹配模式:

            RegExp

            匹配/etc/passwd文件行中含有root字符串的所有行

1awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd

            匹配/etc/passwd文件行中以nginx开头的所有行

1awk 'BEGIN{FS=":"}/^nginx/{print $0}' /etc/passwd

第二种匹配模式:

关系运算符匹配:

  • <            小于
  • >            大于
  • <=          小于等于
  • >=          大于等于
  • ==          等于
  • !=           不等于
  • ~            匹配正则表达式
  • !~           不匹配正则表达式

(1)、以:为分隔符,匹配/etc/passwd文件中第3个字段小于50的所有行信息

1awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd

(2)、以:为分隔符,匹配/etc/passwd文件中第3个字段大于50的所有行信息

1awk 'BEGIN{FS=":"}$3>50{print $0}' /etc/passwd

(3)、以:为分隔符,匹配/etc/passwd文件中第7个字段为/bin/bash的所有行信息

1awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd

(4)、以:为分隔符,匹配/etc/passwd文件中第7个字段不为/bin/bash的所有行信息

1awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' /etc/passwd

(5)、以:为分隔符,匹配/etc/passwd中第3个字段包含3个以上数字的所有行信息

1awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/passwd

布尔运算符:

  • || 或
  • && 与
  • !非

(1)、以:为分隔符,匹配/etc/passwd文件中包含nginx或apache的所有行信息

1awk 'BEGIN{FS=":"}$1=="nginx" || $1=="apache" {print $0}' /etc/passwd

(2)、以:为分隔符,匹配/etc/passwd文件中第3个字段小于50并且第4个字段大于50的所有行信息

1awk 'BEGIN{FS=":"}$3<50 && $4>50 {print $0}' /etc/passwd

算数运算符:

  • + 加
  • - 减
  • * 乘
  • / 除
  • % 取模
  • ++x 在返回x变量之前,x变量加1
  • x++ 在返回x变量之后,x变量加1
  • --x 在返回x变量之前,x变量减1
  • x-- 在返回x变量之后,x变量减1
  • ** 幂运算

awk中的字符串函数:

  • length(str)                      计算长度
  • index(str1,str2)                返回在str1中查询到的str2的位置
  • tolower(str)                    小写转换
  • toupper(str)                    大写转换    
  • split(str,arr,fs)                 分隔字符串,并保存到数组中(索引从1开始)
  • match(str,RE)                  返回正则表达式匹配到的子串的位置,正则表达式写在'//'内
  • substr(str,m,n)                 截取子串,从m个字符开始,截取n位。n若不指定,则默认截取到字符串尾
  • sub(RE,RepStr,str)            替换查找到的第一个子串
  • gsub(RE,RepStr,str)           替换查找到的所有子串

awk是一种语言支持条件语句、循环遍历数组等操作

常用命令:

netstat -n| awk '/^tcp/ {++S[$NF]} END {for (i in S) print i,S[i]}'


一名测试工作者,专注接口测试、自动化测试、性能测试、Python技术。