Linux与bash:2.Linux终端命令之三剑客命令(grep,sed,awk)

Posted new nm个对象

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux与bash:2.Linux终端命令之三剑客命令(grep,sed,awk)相关的知识,希望对你有一定的参考价值。

1.grep讲解

(1)grep的用法

格式:grep + 参数 + 正则表达式+要匹配的内容

其中常用的参数如下:

(2)练习

  • 查找test.txt文件中包含root的内容并显示行号
    grep -n root test.txt
    
  • 查找test.txt文件中不包含root的内容并显示行号
    	grep -nv root test.txt
    
  • 查找以s开头的内容
    grep -E ^s test.txt
    
  • 查找以n结尾的内容
    grep -E n$ test.txt
    

2.sed讲解

(1)sed的用法

grep只能对文本内容进行查找,而sed可以对文本内容进行增删改。

格式:sed [-e<script>] [-f <script文件>]

script中常用的参数:

(2)练习

  • 查看帮助文档

    方法一:
    man sed
    方法二:
    sed -h
    
  • 在test.txt文件的第四行后添加字符串‘ouyi’

    sed -e '4 a ouyi' test.txt
    注意ouyi字符串也会独占一行,显示为第五行。
    
  • 在在test.txt文件的第二行前添加字符串‘ouyi’

    sed -e '2 i ouyi' test.txt
    注意ouyi字符串也会独占一行,显示为第二行。
    
  • 全局替换:将test.txt文件中的所有的‘root‘替换为‘hello’

    sed -e 's/root/hello/g' test.txt
    注意:如果不加g参数,只会替换每行中的第一个
    
  • 修改文件内容:将test.txt文件中的所有的‘root‘替换为‘hello’

    sed -i 's/root/hello/g' test.txt
    注意,我们之前使用sed -e来对文件所做的更改,并没有修改文件本身。而使用sed -i会直接修改掉原文件
    

总结:sed和grep都是对文件进行操作,但grep只能对文件进行匹配查找,而sed更多是对文件进行修改后显示。

3.awk讲解

(1)awk用法



格式:awk 'pattern+action' 文件名

常用参数如下:

(2)练习

1.打印/etc/passwd文件中的包含’root‘关键字的所有内容

  • 1.先cat查看相关文件内容的格式

  • 2.通过查看文件内容我们发现,文件每行是以’:‘为分割符的,所以我们需要使用-F参数指定以”:“来对每一行进行切片

    awk -F : '/root/ {print $0}' /etc/passwd
    注意:$0表示每行切片后的整条记录,$1表示切片后的第一段内容
    

2.打印/etc/passwd文件中的包含’root‘关键字的所以记录的shell内容

  • 1.通过查看文件内容,我们知道记录中的shell内容对应每行切片后的第七段内容

  • 2.我们可以通过打印$7来实现只显示shell内容

  • awk -F : '/root/ {print $7}' /etc/passwd
    

3.打印/etc/passwd文件的第二行的所有内容

  • 1.使用参数NR来匹配需要的行数

  • awk -F : 'NR==2 {print $0}' /etc/passwd
    

4.使用begin加入标题,并且打印所有记录的第一,第二片段内容

  • awk -F : 'BEGIN{print "start"} {print $1,$2}' /etc/passwd
    

5.使用awk进行分段匹配

awk -F : '$9~/root/ {print $0}'------匹配第九段内容含root的记录

6.awk打印倒数第一,倒数第二列字段

```
cat nginx.log | awk '{print $(NF),$(NF-1)}'
# $(NF)表示倒数第一行,$(NF-1)表示倒数第二行
```

7.awk词典进行分类汇总

```
cat test.txt | awk '{d[$1]+=$2} END{for(k in d) print k,d[k]}'
# d[$1]在这里分别对应d[a],d[b]
```

结果如下:

4.Linux三剑客实战

(1)实战1:查找nginx.log日志文件中,404和500的报错的信息。以及报错的总行数

  • 分析查看nginx.log日志文件内容,我们发现每条记录的状态码格式为数字且前后都有空格,状态码的位置按照空格作为域分隔符,位于第9段。

  • 使用grep命令来实现

    • 方法一:
      (1)查看404和500的报错信息
      grep -E '\\s404\\s|\\s500\\s' nginx.log
      参数解析:
      -E:因为grep不支持扩展正则,这里要使用带’或‘的正则表达式,所以必须加上-E参数
      (2)统计404和500报错信息的总记录数
      grep -E '\\s404\\s|\\s500\\s' nginx.log | wc -l
      参数解析:
      wc -l : 用户输出查找到的记录总数
      方法二:
      (1)查看404和500的报错信息
      cat nginx.log | grep -E '\\s404\\s|\\s500\\s'
      (2)统计404和500报错信息的总记录数
      cat nginx.log | grep -E '\\s404\\s|\\s500\\s' | wc -l
      
  • 所以awk命令实现

    • 方法一:
      (1)查看404和500的报错信息
      awk '/\\s404\\s|\\s500\\s/ {print$0}' nginx.log
      解析:
      因为awk默认就是以空格作为域分隔符,所以不需要指定-F参数
      (2)统计404和500报错信息的总记录数
      awk '/\\s404\\s|\\s500\\s/ {print$0}' nginx.log | wc -l
      方法二:
      (1)查看404和500的报错信息
      cat nginx.log | awk '$9~/404|500/ {print$0}'
      参数解析:
      $9~/404|500/ : 表示使用第九列的内容去匹配后面的正则表达式
      (2)统计404和500报错信息的总记录数
      cat nginx.log | awk '$9~/404|500/ {print$0}' | wc -l
      

(2)实战2:找出日志中出现次数最多的前三个ip

  • 分析查看nginx.log日志文件内容,我们发现ip地址的位置为每条记录的开头

  • 实现步骤一:使用awk单独提取出ip地址

    • awk '{print$1}' nginx.log
      
  • 实现步骤二:进行排序

    • awk '{print$1}' nginx.log | sort
      参数解析:
      sort : 排序
      
  • 实现步骤三:相同的ip地址合并

    • awk '{print$1}' nginx.log | sort | uniq -c
      参数解析:
      uniq : 将相同的记录合并,加上参数’-c‘可以显示出合并前该内容出现的次数
      

  • 实现步骤四:在进行一次排序,

    • awk '{print$1}' nginx.log | sort | uniq -c | sort  -nr
      参数解析:
      sort  -nr : sort排序默认是字典序且默认为升序,加上参数’-n‘表示按照数字大小排序,加上参数’-r‘表示按照降序排列
      
  • 实现步骤四:取前三条记录

    • awk '{print$1}' nginx.log | sort | uniq -c | sort  -nr | head -3
      参数解析:
      head -3 : 表示取出前三条数据
      也可以使用命令:
      awk '{print$1}' nginx.log | sort | uniq -c | sort  -nr | awk 'NR<=3 {print$0}'
      

(3)实战3:全局替换

将nginx.log日志文件中的’/topics/‘后面的数字替换为number字符串

  • 分析查看nginx.log日志文件内容,我们发现/topics/后面的内容是变化的数字

  • 使用sed实现全局替换

    • sed -e 's#/topics/[0-9]*#/topics/number#g' nginx.log
      参数解析:
      # : 在sed中用于分隔替换前后字符的标识不一定是’/‘,也可以是其他符号,这里使用#
      

(4)实战4:ip横排

我们如果用awk提取的ip地址,是没有在同一行的,如果我们要实现把所有的ip地址放在同一行怎么实现呢?

  • 我们知道,换行是因为末尾有一个换行符,那么我们把换行符换位其他字符是否就可以了呢

    • awk '{print$1}' nginx.log | sed 's/\\n/ /g' 
      结果并没有变为一行,因为sed在处理每一行时,并没有读取到换行符
      

  • 优化代码,在sed中加入N参数,将后面一行内容追加到前一行中

    • awk '{print$1}' nginx.log | sed 'N;s/\\n/ /g' 
      结果:只是把两行内容合并了,因为每一行中,追加操作只执行了一次
      

  • 再次优化代码:

    • awk '{print$1}' nginx.log | sed ':2;N;s/\\n/ /g;t2' 
      结果成功了。
      解析:
      :2 ---表示创建一个标记2(可以是其他数字)
      t2 ---表示跳转到标记2
      

以上是关于Linux与bash:2.Linux终端命令之三剑客命令(grep,sed,awk)的主要内容,如果未能解决你的问题,请参考以下文章

正则与sed,grep,awk三剑客

Linux常用基本命令:三剑客命令之-awk模式用法

Linux三剑客之grep命令详解

3.自学Linux之路:shell特性之三:命令历史

Linux与bash:4.Linux终端命令之性能统计命令

Linux与bash:3.Linux终端命令之进阶命令(curl,jq,sort,uniq,wc)