设为首页 加入收藏

TOP

Linux:管道命令与文本处理三剑客(grep、sed、awk)(一)
2023-07-23 13:34:05 】 浏览:69
Tags:Linux 管道命 文本处 grep sed awk

1 管道命令(pipe)介绍

众所周知,bash命令执行的时候会输出信息,但有时这些信息必须要经过几次处理之后才能得到我们想要的格式,此时应该如何处置?这就牵涉到 管道命令(pipe) 了。管道命令使用的是|这个界定符号。另外,管道命令与连续执行命令是不一样的,这点下面我们会说明。

我们先来看一个管道命令的例子。假设我们需要看/etc目录下有多少文件,那么可以利用ls /etc来查看,不过由于文件数量太多,导致一口气就将屏幕塞满了,而不知道前面输出的内容是啥:

root@orion-orion:~ ls -al /etc                                                               
total 944
drwxr-xr-x 1 root root    4096 Feb 19 11:38 .
drwxr-xr-x 1 root root    4096 Nov 23  2021 ..
drwxr-xr-x 3 root root    4096 Jun  5  2021 .java
...
drwxr-xr-x 2 root root    4096 Jul 24  2018 xfce4

此时,我们可以使用less命令的协助:

root@orion-orion:~ ls -al /etc | less 
total 944
drwxr-xr-x 1 root root    4096 Feb 19 11:38 .
drwxr-xr-x 1 root root    4096 Nov 23  2021 ..
drwxr-xr-x 3 root root    4096 Jun  5  2021 .java
:

如此一来,使用ls命令输出的内容就能够被less读取,并且利用less的功能,我们就能够前后翻动相关的信息了。其中的关键就是这个管道命令|。管道命令|仅能处理前一个命令传来的标准输出信息,而对于标准错误信息并没有直接处理能力。那么整体的管道命令可以使用下图表示:

在每个管道后面接的第一个数据必定是命令,而且这个命令必须要能够接受标准输出的数据才行,这样的命令才可为管道命令。例如lessgrepsedawk等都是可以接受标准输入的管道命令,而lscpmv就不是管道命令,因为它们并不会接受来自stdin的数据。总结一下,管道命令主要有两个需要注意的地方:

  • 管道命令仅会处理标准输出,对于标准错误会予以忽略
  • 管道命令必须要能够接受来自前一个命令的数据成为标准输入继续处理才行(这也是其与由;隔开的连续执行命令之不同)。

如果我们强行让标准错误为管道命令所用,那么可以使用2>&1将标准错误2>重定向到标准输出1>

接下来我们选取grepsedawk这三个用于文本处理的管道命令来进行介绍。这三个命令可谓是Linux下操作文本的三大利器,合称Linux文本处理三剑客

2 行选取命令grep

grep命令可以一行一行地分析信息,若某行含有我们所需要的信息,则就将该行拿出来。简单的语法如下:

grep [-acinv] [--color=auto] '查找字符' filename

它的选项与参数如下:

  • -a:将二进制文件以文本文件的方式查找数据。
  • -c:计算找到'查找字符'的次数。
  • -i:忽略大小写的不同,所以大小写视为相同。
  • -n:顺便输出行号。
  • -v:反向选择,亦即显示出没有'查找字符'内容的那些行。

下面展示几个例子。

范例一:将last当中,有出现root的那一行就显示出来。

root@orion-orion:~ last | grep 'root'
root     pts/2        10.249.252.8     Mon Apr  6 06:08 - 09:02  (02:54)
root     pts/1        10.249.252.8     Mon Apr  6 06:05 - 06:08  (00:03)
root     pts/1        10.249.252.8     Mon Apr  6 03:13 - 06:05  (02:51)
...
root     pts/1        :1               Tue Jul 24 06:44 - 06:45  (00:00)
root     pts/1        172.17.0.1       Tue Apr 10 14:23 - 14:23  (00:00)
root     pts/1        127.0.0.1        Tue Apr 10 08:57 - 08:57  (00:00)

这里前3行是我们校内的局域网IP(以10.249打头),172.17.0.1是Docker中默认网桥docker0的IP地址,127.0.0.1为本地回环地址。
范例二:与范例一相反,只要没有root的就取出。

root@orion-orion:~ last | grep -v 'root'
person   pts/1        127.0.0.1        Tue Apr 10 08:54 - 08:54  (00:00)

范例三:在last的输出信息中,只要有root就取出,并且仅取第一栏:

root@orion-orion:~ last | grep "root" | awk '{print $1}' 
root
root
root
...

这里用到了我们后面要讲的awk命令,这一命令用于将一行分为多个字段来处理,我们后面将会详细介绍。
范例四:取出/etc/adduser.conf内含UID的那几行,且将找到的关键字部分用特殊颜色显示出来:

root@orion-orion:~ grep --color=auto "UID" /etc/adduser.conf                                                                   
# FIRST_SYSTEM_[GU]ID to LAST_SYSTEM_[GU]ID inclusive is the range for UIDs
# package, may assume that UIDs less than 100 are unallocated.
FIRST_SYSTEM_UID=100
LAST_SYSTEM_UID=999
# FIRST_[GU]ID to LAST_[GU]ID inclusive is the range of UIDs of dynamically
FIRST_UID=1000
LAST_UID=29999

可以看到找到的关键字部分用红色显示(当然这里的代码块看不出来效果,需要在终端进行渲染)。注意,在我的Ubuntu 18.04系统中默认的grep已经主动使用--color=auto选项在alias中了,因此不用手动加--color=auto也会标红(事实上,在我本地的Mac系统中也是如此)。

3 行操作命令sed

前面我们说过,grep命令可以解析一行文字,若该行含有某关键词就会将其整行列出来。接下来我们要讲的sed命令也是一个管道命令(可以分析标准输入),它还可以对特定行进行新增、删除、替换等sed的用法如下:

sed [-nefr] [操作]

它的选项与参数如下:

  • -n:使用安静(silent)模式。在一般的sed用法中,所有来自stdin的数据一般都会被列出到屏幕上,但如果加上-n参数后,则只有经过sed选择的那些行才会被列出来。
  • -e:使sed的操作结果由屏幕输出,而改变原有文件(默认已选该参数, 与-i的直接修改文件相反)。
  • -f:从一个文件内读取将要执行的sed操作,-f filename可以执行filename中写好的sed操作。
  • -rsed的操作使用的是扩展型正则表达式的语法(默认是基础正则表达式语法)。
  • -i:直接修改读取的文件内容,而不是由屏幕输出。

关于其中的[操作]部分,其格式如下:

[n1[,n2]]function

n1, n2:不一定会存在,一般代表选择进

首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇CentOS7---部署Tomcat和安装Jpress 下一篇linux vi命令详解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目