linux文本三剑客(grep,sed,awk)使用

发布时间:2024年01月13日

一、grep

grep概念

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

grep的工作方式是这样的,它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到标准输出,不影响源原文件内容。

grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可以进行一些自动化的文本处理工作。

egrep = grep -E:扩展的正则表达式(除了<,>,\b使用其他正则都可以去掉)

grep使用

grep常用的选项:

-n :显示行号
-o :只显示匹配的内容
-q :静默模式,没有任何输出,得用$?来判断执行成功没有,即有没有过滤到想要的内容
-l :如果匹配成功,则只将文件名打印出来,失败则不打印,通常-rl一起用,grep -rl 'root' /etc
-A :如果匹配成功,则将匹配行及其后n行一起打印出来
-B :如果匹配成功,则将匹配行及其前n行一起打印出来
-C :如果匹配成功,则将匹配行及其前后n行一起打印出来
--color:高亮颜色显示匹配到的字符串
-c :如果匹配成功,则将匹配到的行数打印出来
-E :等于egrep,扩展
-i :忽略大小写
-v :取反,不匹配
-w:匹配单词
-r:递归搜索,不仅搜索当前目录,还要搜索其各级子目录
-s:不显示关于不存在或者无法读取文件的错误信息

常用的一些元字符:
^ 在每行的开始进行匹配
$ 在每行的末尾进行匹配
. 对任何单个字符进行匹配
*对前一项进行0次或多次重复匹配
[str] 对str中的任何单个字符进行匹配
[^str】对任何不在str中的单个字符进行匹配
[a-b] 对a到b之间的任何字符进行匹配
\ 忽略后面一个字符的特殊含义
{n,m} 匹配n到m次,前一个字符
注意:grep要将{}转义,{},egrep不需要转义
[[:alnum:]] 匹配任意一个字母或者数字,等价于[A-Za-z0-9]
[[:alpha:]] 匹配任意一个字母,等价于[A-Za-z]
[[:space:]] 匹配任意一个空白符,包括空格、制表符、换行符以及分页符

grep练习题
1、显示/proc/ meminfo文件中以不区分大小的s开头的行;

grep -i '^s' /proc/meminfo
grep '^[sS]' /proc/meminfo

2、显示/etc/passwd中以nologin结尾的行;

grep 'nologin$' /etc/passwd

3、取出默认shell为/sbin/nologin的用户列表

grep '/sbin/nologin' /etc/passwd | cut -d: -f1

4、取出默认shell为bash,且其用户ID号最小的用户的用户名

5、显示/etc/inittab中以#开头,且后面跟一个或多个空白字符,而后又跟了任意非空白字的行

egrep '^#[[:space:]]+[^[:space:]]*' /etc/inittab

6、显示/etc/inittab中包含了:一个数字:(即两个冒号中间一个数字)的行;

egrep ':[0-9]:' /etc/inittab

7、显示/boot/grub/grub.conf文件中以一个或多个空白字符开头的行

egrep '^[[:space:]]+' /boot/grub2/grub.cfg

8、显示/etc/inittab文件中以一个数字开头并以一个与开头数字相同的数字结尾的行

egrep '(^[0-9]).*\1$' /etc/inittab 

9、找出/proc/ cpuinfo中的,1位数,或2位数;

egrep -o '[0-9]|[0-9][0-9]' /proc/cpuinfo

6、直找ifconfig命令结果中的1-255之间的整数;

ifconfig | egrep -o '[0-9]|[0-9][0-9]|[0-9][0-9][0-9]'

7、显示/var/log/secure文件中包含“Failed”或“FAILED"的行

egrep 'failed|FAILED' /var/log/secure

8、在/etc/passwd列出默认shell为bash的用户列表

grep 'bash' /etc/passwd | cut -d: -f1

9、以长格式列出山/etc/目录下以ns开头、.conf结死的文件信息

ll /etc/ns*.conf

10、高亮显示passwd文件中目号,及其两侧的字符

egrep '[[:alpha:]]:[[:alpha:]]' /etc/passwd

11、匹配/etc/services中开头结尾字母一样的单词

grep -E '^([a-zA-Z]).*\1$' /etc/services

二、sed

sed概念

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

功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,替换文件内容

sed使用

sed option 【inputfile】【script】

常用的选项:
-n,-quiet:不输出模式空间中的内容
-i:直接编辑原文件,默认不对原文件进行操作
-e:可以使用多个命令(脚本)进行操作
-f /path/from/sed_script:从指定的文本中读取处理脚本
-r:使用扩展正则表达式

地址定界

#: #为数字,代表的几行
$: 表示最后一行
/regexp/: 表示能够被regexp匹配;regexp基于正则表达式的匹配
/regexp/I: 匹配时忽略大小写
addr ,addr:指定范围内的所有的行(范围选定)
first~ step:指定起始的位置及步长,例如:1~2表示1,3,5…

常用的编辑命令

d:删除匹配到的行
p:打印模式空间中的内容
a :表示在匹配到的行之前追加内容
i:表示在匹配的行插入内容
s: /regexp/rep1lacement/f1ages:查找替换,把text替换为regexp
常用的f1ages:
g:全局替换,默认只替换第一个
i:不区分大小写
p:如果成功替换则打印

sed扩展:

! : 对指定行以外的所有行应用命令
=  :打印当前行行号
& :代表被替换的内容
:   :实现一行命令语句可以执行多条sed命令
{}  :对单个地址或范围执行批量操作
+ :地址访问内用到的符号,做加法运算

命令练习:

[root@gang ~]# sed -n '2p' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
[root@gang ~]# sed -n '$p' /etc/passwd
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false
[root@gang ~]# sed '/root/p' /etc/passwd -n
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@gang ~]# sed -n '/^S/I p' /proc/meminfo  以s开头,忽略大小写
[root@gang ~]# sed -n '/e$/I p' /etc/passwd   以e结尾,忽略大小写
[root@gang ~]# sed -n '1,5p' /etc/passwd  打印1-5行
[root@gang ~]# sed -n '1~2p' /etc/passwd  以2为步长进行打印
[root@gang ~]# sed -n '1,5 ! p' /etc/passwd  除了1-5,其他都打印
root@gang ~]# sed  '2,10 d' /etc/passwd   2,10行被删除
[root@gang ~]# sed '1 a12345' /etc/passwd   1行后插入内容
root:x:0:0:root:/root:/bin/bash
12345
bin:x:1:1:bin:/bin:/sbin/nologin
[root@gang ~]# sed 's/root/123/g' /etc/passwd   将所有的root都换成123,不加g就换每行的第一个
123:x:0:0:123:/123:/bin/bash
[root@gang ~]# sed '1 s/root/123/2' /etc/passwd  第一行的的第二个root会被替换

[root@gang ~]# head -1 /etc/passwd | sed '1 s/root/123456/g'
123456:x:0:0:123456:/123456:/bin/bash

给文本加注释快速:
[root@gang ~]# sed 's/^/#/' /etc/passwd
#root:x:0:0:root:/root:/bin/bash
#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

删除每行的第一个字母:
[root@gang ~]# sed 's/^.//' /etc/passwd

sed扩展使用:
[root@gang ~]# sed -n '1p;3p' /etc/passwd   打印1,3行内容
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin

sed练习案例:
1、把/etc/passwd复制到/root/test.txt,用sed打印所有行;

[root@gang ~]# cp /etc/passwd -p test.txt

[root@gang ~]# sed ‘p’ test.txt

2、打印test.txt的3到10行;

[root@gang ~]# sed ‘3,10p’ test.txt -n

3、打印test.txt中包含’root’的行;

[root@gang ~]# sed -n ‘/root/p’ test.txt

4、删除test.txt的15行以及以后所有行;

[root@gang ~]# sed ‘15,$ d’ /etc/passwd

5、删除test.txt中包含’bash’的行;

[root@gang ~]# sed ‘/bash/d’ /etc/passwd

6、替换test.txt中’root’为’toor’;

[root@gang ~]# sed ‘s/root/toor/g’ /etc/passwd

7、替换test.txt中’/sbin/nologin’为’/bin/login’

[root@gang ~]# sed ‘s@/sbin/nologin@/bin/login@g’ /etc/passwd

遇到有/的就用其他的分隔符
8、删除test.txt中5到10行中所有的数字;

 [root@gang ~]# sed -r '5,10 s/[0-9]//g' /etc/passwd

9、删除test.txt中所有特殊字符〈除了数字以及大小写字母);

[root@gang ~]# sed -r 's/[^0-9a-Z]//g' /etc/passwd

10、在test.txt 20行到末行最前面加’aaa :
[root@gang ~]# sed ‘20,$ a aaa’ /etc/passwd
11、删除centos7系统/etc/grub2.cfg文件中所有以空白开头的行行首的空白字符

 [root@gang ~]# sed -r 's/ ^[[:space:]]+//g' /etc/grub2-efi.cfg

12、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符

[root@gang ~]# sed -r ‘s/^#[[:space:]]+//g’ /etc/fstab

13、在centos6系统/root/install.log每一行行首增加#号

[root@gang ~]# sed ‘s/^/#/’ /etc/passwd

14、在/etc/fstab文件中不以#开头的行的行首增加#号

 [root@gang ~]# sed 's/^[^#]/#/' /etc/fstab 

16、利用sed 取出ifconfig命令中本机的IPv4地址

ifconfig | sed -n ‘/inet /p’ | awk ‘{print $2}’

面试题:
1.写一个sed命令,修改/tmp/input.txt文件的内容,
要求:
(1)删除所有空行;
(2〉在非空行前面加一个"AAA",在行尾加一个"BBB",即将内容为11111的一行改为: AAA11111BBB
(3) 将123abc456中的内容改为前面的数字和后面的数字交换,小写字母变成大写字母

sed '/^$/d' /tmp/input.txt
sed '/^$/d' /tmp/input.txt | sed -r 's/(.*)/AAA\1BBB/'
sed -r 's/([0-9]{3})(.*)([0-9]{3})/\3\2\1/' /tmp/input.txt | tr 'a-z' 'A-Z'

三、awk

awk概念

awk程序是Unix中的原始awk程序的GNU版本。 awk程序让流编辑迈上了一个新的台阶,它提供了一种
编程语言而不只是编辑器命令。在awk编程语言中,你可以做下面的事情:

定义变量来保存数据;
使用算术和字符串操作符来处理数据;
使用结构化编程概念(比如if-then语句和循环)来为数据处理增加处理逻辑;
通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告。

awk程序的报告生成能力通常用来从大文本文件中提取数据元素,并将它们格式化成可读的报告。其中最完美的例子是格式化日志文件。在日志文件中找出错误行会很难, awk程序可以让你从日志文件中过滤出需要的数据元素,然后你可以将其格式化,使得重要的数据更易于阅读。

awk的主要特性之一是其处理文本文件中数据的能力。它会自动给一行中的每个数据元素分配一个变量。默认情况下, awk会将如下变量分配给它在文本行中发现的数据字段:

  • $0代表整个文本行
  • $1代表文本行中的第1个数据字段
  • $n代表文本行中的第n个数据字段

awk使用

基本语法:

awk options program file

不处理文本文件时需要加上BEGIN
awk内置变量之记录变量:

  • FS:读取文件文本时,所使用字段分隔符
  • OFS:输出分隔符
  • awk -F :
  • OFS=“#”

例子:

[root@manged ~]# awk -F: '{OFS="@@@@"}{print $1,$2}' /etc/passwd
root@@@@x
bin@@@@x
daemon@@@@x

printf命令的使用格式:
1.与print命令格式不同的是,printf需要指定format
2.printf不会自动换行
3.%c :显示字符的ASCII码
4.%d,%i :十进制数
5.%e,%E:科学计数
6.%f:浮点数
7.%s:显示字符串
8.%u:无符号整数
9.%%:显示%本身
修饰符:
N:显示宽度
-:左对齐
+:显示数值符合
例子:

[root@manged ~]# awk -F: '{printf "%-20s %d\n", $1,$3}' /etc/passwd
root                 0
bin                  1
daemon               2
adm                  3
lp                   4

输出重定向:

[root@manged ~]# awk -F: '{printf "%-20s %d\n", $1,$3 > "user.txt"}' /etc/passwd
[root@manged ~]# cat user.txt 
root                 0
bin                  1
daemon               2
adm                  3
lp                   4

awk操作符,数学运算:

[root@manged ~]# awk 'BEGIN{x=2;y=3;print x+y,x*y}'
5 6

awk模式:
跟sed很相似
awk练习命令:

打印行号,与grep -n 一样:
[root@manged ~]# awk '{print NR,$0}' /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
NF表示一行的多少列,NF-1表示一行的倒数第二列
[root@manged ~]# df -h | awk '/\/$/ {print $(NF-1)}'
29%
加号把它转成数字
[root@manged ~]# df -h | awk '/\/$/ {print +$(NF-1)}'
29
匹配root的行:
[root@manged ~]# awk '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

awk练习题:
在/tmp/input.txt写入以学内容:
zhangsan:1343122343:300元
lisi:1352382343:400元
xiaozhang:15320251654:100元
1.取下所有的电话号码

awk -F: '{print $2}' /tmp/input.txt

2.匹配小张的电话号码

awk -F: '/xiaozhang/ {print $2}' /tmp/input.txt 

1.只处理用户ID为奇数的行,并打印用户名和uid号

awk -F: '$3%2==1 {print $1,$3}' /etc/passwd

2.显示系统的普通用户,并打印用户名和ID

[root@manged ~]# awk -F: '$3>=1000 {print $1,$3}' /etc/passwd
nobody 65534
redhat 1000
xixi 4002

3.显示用户shell是’/bin/bash’的用户,并打印用户名

awk -F: '/bash/ {print $1}' /etc/passwd
[root@manged ~]# awk -F: '$NF=="/bin/bash" {print $1}' /etc/passwd
root
redhat
xixi

4.统计系统用户的个数

[root@manged ~]# awk -F: '$3>=201&&$3<1000 {print $1}' /etc/passwd | wc -l
17
文章来源:https://blog.csdn.net/qq_62331653/article/details/135292022
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。