#009 文本过滤好帮手grep

本文详细介绍了grep命令的功能及其使用方法,包括基本语法、常见选项及如何结合正则表达式进行高效文本搜索。通过实际示例展示了如何针对不同场景灵活运用grep进行内容匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文本过滤好帮手grep

写在开头

此篇详细讲解了如何使用grep命令搜索你关心的内容,学完此篇,你可以

  1. 知道grep是什么,能干什么
  2. 了解常用的grep选项
  3. 了解基本正则表达式,搭配grep对文本进行模式匹配

自我介绍

grep是文本搜索工具,它的作用是根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查,并打印匹配到的行。模式:由正则表达式的元字符及文本字符所编出的过滤条件。

这里的目标文本,有两处:

  1. 标准输入
  2. 文件

在给出文件或标准输入后,grep会对匹配一个或多个正则表达式的文本进行搜索,并只输出匹配(或者不匹配)的行或文本。

初露身手

如果还没接触正则表达式,不要害怕,稍后会详细介绍。这里只利用grep搜索完整的keyWord关键字。

目标文本:文件

示例:在/etc/fstab下搜索UUID关键字

#( 06/07/18@12:37上午 )( root@centos7 ):~/mysh
   cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Fri Aug 18 03:51:14 2017
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=59d9ca7b-4f39-4c0c-9334-c56c182076b5 /                       ext4    defaults        1 1
#( 06/07/18@12:38上午 )( root@centos7 ):~/mysh
   grep "UUID" /etc/fstab
UUID=59d9ca7b-4f39-4c0c-9334-c56c182076b5 /                       ext4    defaults        1 1
#( 06/07/18@12:38上午 )( root@centos7 ):~/mysh
   grep 'UUID' /etc/fstab
UUID=59d9ca7b-4f39-4c0c-9334-c56c182076b5 /                       ext4    defaults        1 1
#( 06/07/18@12:38上午 )( root@centos7 ):~/mysh
   grep UUID /etc/fstab
UUID=59d9ca7b-4f39-4c0c-9334-c56c182076b5 /                       ext4    defaults        1 1

目标文本:标准输入

示例: 搜索/目录下是否存在bin目录(管道)

#( 06/07/18@12:43上午 )( root@centos7 ):~
   ls /
backups  bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  users  usr  var
#( 06/07/18@12:43上午 )( root@centos7 ):~
   ls / | grep "bin"
bin
sbin
#( 06/07/18@12:43上午 )( root@centos7 ):~
   ls / | grep 'bin'
bin
sbin
#( 06/07/18@12:43上午 )( root@centos7 ):~
   ls / | grep bin
bin
sbin

示例:在test.txt中搜索fefora(输入重定向)

#( 06/07/18@ 1:02上午 )( root@centos7 ):/tmp/workspace
   cat test.txt
fedora is one of red hat
CentOS is One of Red Hat
Ubantu is One of Debian

#( 06/07/18@ 1:02上午 )( root@centos7 ):/tmp/workspace
   grep "fedora" < test.txt
fedora is one of red hat

正如grep自我介绍中所说,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查,并打印匹配到的行。只要匹配到keyWord就打印出这一行。

然而grep可不只是这么简单。

功能选项

具体用法:

#( 06/07/18@ 1:17上午 )( root@centos7 ):/tmp/workspace
   grep --help
用法: grep [选项]... PATTERN [FILE]...
在每个 FILE 或是标准输入中查找 PATTERN。
默认的 PATTERN 是一个基本正则表达式(缩写为 BRE)。
例如: grep -i 'hello world' menu.h main.c

正则表达式选择与解释:
  -E, --extended-regexp     PATTERN 是一个可扩展的正则表达式(缩写为 ERE)
  -F, --fixed-strings       PATTERN 是一组由断行符分隔的定长字符串。
  -G, --basic-regexp        PATTERN 是一个基本正则表达式(缩写为 BRE)
  -P, --perl-regexp         PATTERN 是一个 Perl 正则表达式
  -e, --regexp=PATTERN      用 PATTERN 来进行匹配操作
  -f, --file=FILE           从 FILE 中取得 PATTERN
  -i, --ignore-case         忽略大小写
  -w, --word-regexp         强制 PATTERN 仅完全匹配字词
  -x, --line-regexp         强制 PATTERN 仅完全匹配一行
  -z, --null-data           一个 0 字节的数据行,但不是空行

输出控制:
  -m, --max-count=NUM       NUM 次匹配后停止
  -b, --byte-offset         输出的同时打印字节偏移
  -n, --line-number         输出的同时打印行号
      --line-buffered       每行输出清空
  -H, --with-filename       为每一匹配项打印文件名
  -h, --no-filename         输出时不显示文件名前缀
      --label=LABEL         将LABEL 作为标准输入文件名前缀
  -o, --only-matching       show only the part of a line matching PATTERN
  -q, --quiet, --silent     suppress all normal output
      --binary-files=TYPE   assume that binary files are TYPE;
                            TYPE is 'binary', 'text', or 'without-match'
  -a, --text                equivalent to --binary-files=text
  -I                        equivalent to --binary-files=without-match
  -d, --directories=ACTION  how to handle directories;
                            ACTION is 'read', 'recurse', or 'skip'
  -D, --devices=ACTION      how to handle devices, FIFOs and sockets;
                            ACTION is 'read' or 'skip'
  -r, --recursive           like --directories=recurse

文件控制:
  -B, --before-context=NUM  打印以文本起始的NUM 行
  -A, --after-context=NUM   打印以文本结尾的NUM 行
  -C, --context=NUM         打印输出文本NUM 行  

常用选项

–color=auto:对匹配到的文本着色后高亮显示(grep别名默认选项)

-i:ignorecase,忽略字符的大小写

#( 06/07/18@ 1:06上午 )( root@centos7 ):/tmp/workspace
   cat test.txt
fedora is one of red hat
CentOS is One of Red Hat
Ubantu is One of Debian

#( 06/07/18@ 1:06上午 )( root@centos7 ):/tmp/workspace
   grep centos test.txt
#( 06/07/18@ 1:06上午 )( root@centos7 ):/tmp/workspace
   grep -i centos test.txt
CentOS is One of Red Hat

-o:仅显示匹配到的字符串本身

#( 06/07/18@ 1:06上午 )( root@centos7 ):/tmp/workspace
   cat test.txt
fedora is one of red hat
CentOS is One of Red Hat
Ubantu is One of Debian

#( 06/07/18@ 1:06上午 )( root@centos7 ):/tmp/workspace
   grep -o fedora test.txt
fedora

-v,—invert-match:显示不能被模式匹配到的行

#( 06/07/18@ 1:06上午 )( root@centos7 ):/tmp/workspace
   cat test.txt
fedora is one of red hat
CentOS is One of Red Hat
Ubantu is One of Debian

#( 06/07/18@ 1:08上午 )( root@centos7 ):/tmp/workspace
   grep -v fedora test.txt
CentOS is One of Red Hat
Ubantu is One of Debian

-q,—quiet,—slient:静默模式,即不输出任何信息

#( 06/07/18@ 1:06上午 )( root@centos7 ):/tmp/workspace
   cat test.txt
fedora is one of red hat
CentOS is One of Red Hat
Ubantu is One of Debian

#( 06/07/18@ 1:09上午 )( root@centos7 ):/tmp/workspace
   grep -q fedora test.txt
#( 06/07/18@ 1:10上午 )( root@centos7 ):/tmp/workspace
   echo $?
0
#( 06/07/18@ 1:11上午 )( root@centos7 ):/tmp/workspace
   grep -q aaaaa test.txt
#( 06/07/18@ 1:11上午 )( root@centos7 ):/tmp/workspace
   echo $?
1

'注意':$?是命令执行结果状态返回值,0代表真,非0代表假

-A NUM:after,后NUM行
-B NUM:before,前NUM行
-C NUM:前后各NUM行

#( 06/07/18@ 1:11上午 )( root@centos7 ):/tmp/workspace
   grep -A1 fedora test.txt
fedora is one of red hat
CentOS is One of Red Hat

#( 06/07/18@ 1:15上午 )( root@centos7 ):/tmp/workspace
   grep -i -A1 centos test.txt
CentOS is One of Red Hat
Ubantu is One of Debian
#( 06/07/18@ 1:17上午 )( root@centos7 ):/tmp/workspace
   grep -i -B1 centos test.txt
fedora is one of red hat
CentOS is One of Red Hat
#( 06/07/18@ 1:17上午 )( root@centos7 ):/tmp/workspace
   grep -i -C1 centos test.txt
fedora is one of red hat
CentOS is One of Red Hat
Ubantu is One of Debian

grep的左膀右臂:正则表达式

what is 正则

正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)。一个正则表达式通常被称为一个模式(pattern),为用来描述或者匹配一系列匹配某个句法规则的字符串。

这里所讲正则表达式不代表正则的所有模式,但基本满足我们运用它结合grep来对文本进行“模式”过滤。

元字符

* 字符匹配
     .     :匹配任意单个字符
     []    :匹配范围内字符
     [\^]  :取反范围内字符
* 匹配次数
     *     :匹配次数
     \?    :匹配0次或者1次
     \+    :至少匹配1次
     \(m,n\):匹配(m,n)次
* 位置锚定
     ^    :行首锚定:用于模式的最左侧
     $     :行尾锚定:用于模式最右侧
     ^PATTERN$  :匹配整行
     ^$         :空白行
     ^[[:space:]]*$    :空行或包含空白字符的行
     单词 :非特殊字符组成的连续字符(字符串)都称为单词
        \< 或 \b:词首
        \> 或 \b:词尾
        \<PATTERN\>:匹配完整单词
* 分组及引用
    \( \):将一个或多个字符绑在一起,当做一个整体进行处理
        注意:分组括号中的模式匹配到的内容会被正则表达式引擎自动记录于内部的变量中,这些变量为:
        \1:模式从左侧其,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符
        \2
        \3
        ….

正则与grep

grep 结合正则表达式能做很多优美的事情。

示例:

#示例文件内容

#( 06/07/18@11:27下午 )( root@centos7 ):/tmp/workspace
   cat test.txt
fedora is one of red hat
CentOS is One of Red Hat
Ubantu is One of Debian


#1. 元字符.匹配任意单个字符

#( 06/07/18@11:27下午 )( root@centos7 ):/tmp/workspace
   cat test.txt | grep "f..o"
fedora is one of red hat

#2. 元字符.*组合匹配f ~ e

 #( 06/07/18@11:42下午 )( root@centos7 ):/tmp/workspace
   cat test.txt | grep "f.*e"
fedora is one of red hat
CentOS is One of Red Hat
Ubantu is One of Debian

#3. 元字符[]匹配范围内字符

#( 06/07/18@11:42下午 )( root@centos7 ):/tmp/workspace
   cat test.txt | grep "[fCU].*f"
fedora is one of red hat
CentOS is One of Red Hat
Ubantu is One of Debian

#4. 元字符[^]结合行首锚定^匹配行首不是某些字符

#( 06/07/18@11:47下午 )( root@centos7 ):/tmp/workspace
   cat test.txt | grep "^[^fC].*f"
Ubantu is One of Debian

grep还可以将规则(模式)定义在一个文件中,通过读取文件来匹配标准输入。

示例:

#1.从文件中读取规则,并过滤文本内容

#( 06/10/18@10:16上午 )( root@centos7 ):/tmp/workspace
   cat rule.txt
centos
redhat
#( 06/10/18@10:16上午 )( root@centos7 ):/tmp/workspace
   cat rule.txt | grep -i -f rule.txt
centos
redhat

#2.从文件中读取规则,并显示匹配内容的那一行的行号 (注意合并短选项时f选项要放在最后)
#( 06/10/18@10:19上午 )( root@centos7 ):/tmp/workspace
   cat rule.txt | grep -inf  rule.txt
1:centos
2:redhat

我来试一试

#1. 显示/proc/meminfo文件中以大写或小写S开头的行;用两种方式;

#( 06/02/18@10:20上午 )( root@centos7 ):~
   cat /proc/meminfo | grep "^[Ss]"
SwapCached:            0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Shmem:             98612 kB
Slab:             116884 kB
SReclaimable:     105708 kB
SUnreclaim:        11176 kB
#( 06/02/18@10:20上午 )( root@centos7 ):~
   cat /proc/meminfo| grep -i "^s"
SwapCached:            0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Shmem:             98612 kB
Slab:             116884 kB
SReclaimable:     105708 kB
SUnreclaim:        11176 kB

#2. 显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;

#( 06/02/18@10:21上午 )( root@centos7 ):~
   cat /etc/passwd | grep -v "/sbin/nologin$"
root:x:0:0:root:/root:/bin/zsh
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
admin:x:1000:1000::/home/admin:/bin/zsh
hadoop:x:2000:2000:hadoop:/home/hadoop:/bin/bash

#3. 显示/etc/passwd文件中其默认shell为/bin/bash的用户;

#( 06/02/18@10:34上午 )( root@centos7 ):~
   cat /etc/passwd | grep "/bin/bash$"
hadoop:x:2000:2000:hadoop:/home/hadoop:/bin/bash

#4. 找出/etc/passwd文件中的一位数或两位数;

#( 06/02/18@10:39上午 )( root@centos7 ):~
   cat /etc/passwd | grep -E "\<[0-9][0-9]?\>"
root:x:0:0:root:/root:/bin/zsh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

#5. 显示/boot/grub/grub.conf中以至少一个空白字符开头的行;

#( 06/02/18@10:44上午 )( root@centos7 ):~
   cat /boot/grub2/grub.cfg | grep -E "^[[:space:]]+"
  load_env
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
   set default="${saved_entry}"

#6. 显示/etc/fstab文件中以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;

#( 06/02/18@10:58上午 )( root@centos7 ):~
   cat /etc/fstab | grep -E "^#[[:space:]]+"
# /etc/fstab
# Created by anaconda on Fri Aug 18 03:51:14 2017
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

#7. 打出netstat -tan命令执行结果中以‘LISTEN’,后或跟空白字符结尾的行;

#( 06/02/18@10:59上午 )( root@centos7 ):~
   netstat -tan | grep -E "\<LISTEN[[:space:]]*$"
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:32000         0.0.0.0:*               LISTEN

#8. 添加用户bash, testbash, basher, nologin (此一个用户的shell为/sbin/nologin),而后找出当前系统上其用户名和默认shell相同的用户的信息;

#( 06/02/18@ 1:04下午 )( root@centos7 ):~
   vim mysh/add_4_user.sh
#( 06/02/18@ 1:05下午 )( root@centos7 ):~
   cat mysh/add_4_user.sh
useradd bash
useradd testbash
useradd basher
useradd -s /sbin/nologin nologin
#( 06/02/18@ 1:05下午 )( root@centos7 ):~
   tail -4 /etc/passwd
bash:x:2001:2001::/home/bash:/bin/bash
testbash:x:2002:2002::/home/testbash:/bin/bash
basher:x:2003:2003::/home/basher:/bin/bash
nologin:x:2004:2004::/home/nologin:/sbin/nologin
#( 06/02/18@ 1:06下午 )( root@centos7 ):~
   tail -4 /etc/passwd | grep "\(\<[a-z]\+\>\).*\1$"
bash:x:2001:2001::/home/bash:/bin/bash
nologin:x:2004:2004::/home/nologin:/sbin/nologin
#( 06/02/18@ 1:06下午 )( root@centos7 ):~
   tail -4 /etc/passwd | grep -E "(\<[a-z]+\>).*\1$"
bash:x:2001:2001::/home/bash:/bin/bash
nologin:x:2004:2004::/home/nologin:/sbin/nologin

写在最后

grep结合正则表达式可以过滤出你想要内容,在脚本中也可以通过grep查找关键词,利用其命令状态返回值做判断条件,来确定某个内容是否存在哟。grep这个文本过滤工具,你get到了吗?\^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值