目 录CONTENT

文章目录

Linux三剑客grep、sed和awk

vanegoo
2024-04-22 / 1 评论 / 0 点赞 / 25 阅读 / 14899 字 / 正在检测是否收录...

前置:正则表达式

grep

文本过滤工具,支持基本正则

语法格式:

grep [option] PATTERN [FILE...]

常用选项

  • --color=auto 对匹配到的文本着色显示

  • -A # 后#行

  • -B # 前#行

  • -C # 前后各#行

  • -c 统计匹配的行数

  • -e 实现多个选项间的逻辑or关系

  • -E 使用ERE,相当于egrep

  • -F 相当于fgrep,不支持正则表达式

  • -i 忽略字符大小写

  • -n 显示匹配的行号

  • -o 仅显示匹配到的字符串

  • -q 静默模式,不输出任何信息

  • -v 显示不被pattern匹配到的行

  • -w 匹配整个单词

示例:

# 查找文件内容包含root的行
[root@demo ~]# grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
[root@demo ~]# 

# 查找不包含root的行
[root@demo ~]# grep -nv root /etc/passwd
2:bin:x:1:1:bin:/bin:/sbin/nologin
3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
4:adm:x:3:4:adm:/var/adm:/sbin/nologin
......

# 查找以s开头的行
[root@demo ~]# grep -n ^s /etc/passwd
6:sync:x:5:0:sync:/sbin:/bin/sync
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
......

# 查找以n结尾的行
[root@demo ~]# grep -n n$ /etc/passwd
2:bin:x:1:1:bin:/bin:/sbin/nologin
3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
4:adm:x:3:4:adm:/var/adm:/sbin/nologin
......

sed

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

语法格式:

sed [options] '[地址定界] command' file(s)

选项

  • -n 不输出模式空间内容到屏幕,即不自动打印

  • -e 多点编辑

  • -f /PATH/SCRIPT_FILE: 从指定文件中读取编辑脚本

  • -r 支持使用扩展正则表达式

  • -i 直接编辑文件

  • -i.bak 备份文件并原处编辑

script 地址定界

  1. 不给地址:对全文进行处理

  2. 单地址:

    • #: 指定的行,$:最后一行

    • /pattern/:被此处模式所能够匹配到的每一行

  3. 地址范围:

    • #,#

    • #,+#

    • /pat1/,/pat2/

    • `#,/pat1/

  4. ~:步进

    • 1~2 奇数行,例:sed -n '1~2p' 只打印奇数行 (1~2 从第1行,一次加2行)

    • 2~2 偶数行,例: sed -n '2~2p' 只打印偶数行

编辑命令

  1. a [\]text1 在指定行后面追加文本,支持使用\n实现多行追加

  2. c [\]text 替换行为单行或多行文本

  3. d 删除模式空间匹配的行,并立即启用下一轮循环

  4. D 删除 当前模式空间开端至\n 的内容(不再传 至标准输出),放弃之后的命令,但是对剩余模式空间重新执行sed

  5. g 从保持空间取出数据覆盖至模式空间

  6. G:从保持空间取出内容追加至模式空间

  7. h 把模式空间中的内容覆盖至保持空间中

  8. H 把模式空间中的内容追加至保持空间中

  9. i [\]text 在行前面插入文本

  10. n 读取匹配到的行的下一行覆盖 至模式空间

  11. N 读取匹配到的行的下一行追加 至模式空间

  12. p 打印当前模式空间内容,追加到默认输出之后

  13. r /path/somefile 读取指定文件的文本至模式空间中匹配到的行后

  14. w /path/somefile 保存模式匹配的行至指定文件

  15. x 把模式空间中的内容与保持空间中的内容进行互换

  16. = 为模式空间中的行打印行号

  17. ! 模式空间中匹配行取反处理

  18. s///:查找替换,支持使用其它分隔符,s@@@,s###

    • 替换标记:

      • g 行内全局替换

      • p 显示替换成功的行

      • w /PATH/TO/SOMEFILE 将替换成功的行保存至文件中

示例:

# 打印文件第2行
sed -n 2p /etc/passwd

# 打印文件第2-5行
sed -n 2,5p /etc/passwd

##常用选项演示
[root@demo ~]# cat demo
aaa
bbbb
AABBCCDD

[root@demo ~]# sed "/aaa/p" demo  #匹配到的行会打印一遍,不匹配的行也会打印
aaa
aaa
bbbb
AABBCCDD

[root@demo ~]# sed -n "/aaa/p" demo  #-n不显示没匹配的行
aaa

[root@demo ~]# sed -e "s/a/A/" -e "s/b/B/" demo  #-e多点编辑
Aaa
Bbbb
AABBCCDD

[root@demo ~]# cat sedscript.txt
s/A/a/g

[root@demo ~]# sed -f sedscript.txt demo  #-f使用文件处理
aaa
bbbb
aaBBCCDD

[root@demo ~]# sed -i.bak "s/a/A/g" demo  #-i直接对文件进行处理

[root@demo ~]# cat demo
AAA
bbbb
AABBCCDD

[root@demo ~]# cat demo.bak
aaa
bbbb
AABBCCDD

地址定界示例

[root@demo ~]# cat demo
aaa
bbbb
AABBCCDD

[root@demo ~]# sed -n "p" demo  #不指定行,打印全文
aaa
bbbb
AABBCCDD

[root@demo ~]# sed "2s/b/B/g" demo  #替换第2行的b->B
aaa
BBBB
AABBCCDD

[root@demo ~]# sed -n "/aaa/p" demo
aaa

[root@demo ~]# sed -n "1,2p" demo  #打印1-2行
aaa
bbbb

[root@demo ~]# sed -n "/aaa/,/DD/p" demo
aaa
bbbb
AABBCCDD

[root@demo ~]# sed -n "2,/DD/p" demo
bbbb
AABBCCDD

[root@demo ~]# sed "1~2s/[aA]/E/g" demo  #将奇数行的a或A替换为E
EEE
bbbb
EEBBCCDD

编辑命令示例

[root@demo ~]# cat demo
aaa
bbbb
AABBCCDD

[root@demo ~]# sed "2d" demo  #删除第2行
aaa
AABBCCDD

[root@demo ~]# sed -n "2p" demo  #打印第2行
bbbb

[root@demo ~]# sed "2a123" demo  #在第2行后加123
aaa
bbbb
123
AABBCCDD

[root@demo ~]# sed "1i123" demo  #在第1行前加123
123
aaa
bbbb
AABBCCDD

[root@demo ~]# sed "3c123\n456" demo  #替换第3行内容
aaa
bbbb
123
456

[root@demo ~]# sed -n "3w/root/demo3" demo  #保存第3行的内容到demo3文件中

[root@demo ~]# cat demo3
AABBCCDD

[root@demo ~]# sed "1r/root/demo3" demo  #读取demo3的内容到第1行后
aaa
AABBCCDD
bbbb
AABBCCDD

[root@demo ~]# sed -n "=" demo  #=打印行号
1
2
3       

[root@demo ~]# sed -n '2!p' demo  #打印除了第2行的内容
aaa
AABBCCDD

[root@demo ~]# sed 's@[a-z]@\u&@g' demo  #将全文的小写字母替换为大写字母
AAA
BBBB
AABBCCDD

一个有意思的案例

##倒序输出文本内容
[root@demo ~]# cat num.txt
One
Two
Three
[root@demo ~]# sed '1!G;h;$!d' num.txt
Three
Two
One

sed常用实例

awk

报告生成器,格式化文本输出,有多种版本:New awk(nawk),GNU awk( gawk)用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。

它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。

语法:

awk [options] 'program' var=value file…
awk [options] -f programfile var=value file…
awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ...

program: pattern{action statements;..}

  • pattern部分决定动作语句何时触发及触发事件

    • BEGIN,END

  • action statements对数据进行处理,放在{}内指明

    • print, printf

选项

  • -F 指明输入时用到的字段分隔符

  • -v var=value 自定义变量

# 打印文件第一列
awk -F ':' '{print $1}' /etc/passwd

# 输出第1、3、6列,以制表符分隔
awk -F ':' '{print $1,$3,$6}' OFS="\t" /etc/passwd

分隔符、域和记录

awk执行时,由分隔符分隔的字段(域)标记1,1,2..n称为域标识,n称为域标识,0为所有域。
省略action,则默认执行 print $0 的操作。

变量

  • FS:输入字段分隔符;

  • OFS:输出字段分隔符;

  • RS:输入记录分隔符;

  • ORS:输出记录分隔符;

  • NF:字段数量;

  • NR:记录号;

  • NFR:各文件分别计数,记录号。

  • FILENAME:当前文件名;

  • ARGC:命令行的参数;

  • ARGV:数组,保存的是命令行所给定的各参数。

注意:以上都是内置变量,在引用时不需要前面加$,每新建一个变量,都需要加个-v,与变量名之间有无空格都可以,变量可以在引用之后再声明,但那一行的输出会输出空行。

printf命令(格式化输出)

printf “FORMAT” , item1, item2, ... 不会自动换行,FORMAT中需要分别为后面每个item指定格式符。

格式符

  • %c 显示字符的ASCII码

  • %d, %i 显示十进制整数

  • %e, %E 显示科学计数法数值

  • %f 显示为浮点数

  • %g, %G 以科学计数法或浮点形式显示数值

  • %s 显示字符串

  • %u 无符号整数

  • %% 显示%自身

修饰符

  • #[.#] 第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f

  • - 左对齐(默认右对齐) %-15s

  • + 显示数值的正负符号 %+d

操作符

  1. 算术操作符:x+y, x-y, x*y, x/y, x^y, x%y

  2. -x: 转换为负数

  3. +x: 转换为数值

  4. 比较操作符:==, !=, >, >=, <, <=

  5. 模式匹配符:~:左边是否和右边匹配包含 !~:是否不匹配

  6. 逻辑操作符:与&&,或||,非!

  7. 函数调用:function_name(argu1, argu2, ...)

  8. 条件表达式(三目表达式):selector?if-true-expression:if-false-expression

PATTERN:根据pattern条件,过滤匹配的行,再做处理

  1. 如果未指定:空模式,匹配每一行

  2. /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来

  3. relational expression: 关系表达式,结果为“真”才会被处理

  4. line ranges:行范围 startline,endline:/pat1/,/pat2/不支持直接给出数字格式

  5. BEGIN/END模式

awk控制语句

  1. { statements;… } 组合语句

  2. if(condition) {statements;…}

  3. if(condition) {statements;…} else {statements;…}

  4. while(conditon) {statments;…}

  5. do {statements;…} while(condition)

  6. for(expr1;expr2;expr3) {statements;…}

  7. break

  8. continue

  9. delete array[index]

  10. delete array

  11. exit

awk [-F|-v] '行数筛选{XXX;XXX;printf “”,XXX,XXX}'


grep awk sed对比

grep 主要用于搜索某些字符串;

sed,awk 用于处理文本 ;

  grep基本是以行为单位处理文本的, 而awk可以做更细分的处理,通过指定分隔符将一行(一条记录)划分为多个字段,以字段为单位处理文本。awk中支持C语法,可以有分支条件判断、循环语句等,相当于一个小型编程语言。

  awk功能比较多是一个编程语言了。 grep功能简单,就是一个简单的正则表达式的匹配。 awk的功能依赖于grep。

  grep可以理解为主要作用是在一个文件中查找过滤需要的内容。awk不是过滤查找,而是文本处理工具,是把一个文件处理成你想要的格式。

  AWK的功能是什么?与sed和grep很相似,awk是一种样式扫描与处理工具。但其功能却大大强于sed和grep。awk提供了极其强大的功能:它几乎可以完成grep和sed所能完成的全部工作,同时,它还可以可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上,awk的确拥有自己的语言:awk程序设计语言,awk的三位创建者已将它正式定义为:样式扫描和处理语言。 使用awk的第一个理由是基于文本的样式扫描和处理是我们经常做的工作,awk所做的工作有些象数据库,但与数据库不同的是,它处理的是文本文件,这些文件没有专门的存储格式,普通的人们就能编辑、阅读、理解和处理它们。而数据库文件往往具有特殊的存储格式,这使得它们必须用数据库处理程序来处理它们。既然这种类似于数据库的处理工作我们经常会遇到,我们就应当找到处理它们的简便易行的方法,UNIX有很多这方面的工具,例如sed 、grep、sort以及find等等,awk是其中十分优秀的一种。

  使用awk的第二个理由是awk是一个简单的工具,当然这是相对于其强大的功能来说的。的确,UNIX有许多优秀的工具,例如UNIX天然的开发工具C语言及其延续C++就非常的优秀。但相对于它们来说,awk完成同样的功能要方便和简捷得多。这首先是因为awk提供了适应多种需要的解决方案:从解决简单问题的awk命令行到复杂而精巧的awk程序设计语言,这样做的好处是,你可以不必用复杂的方法去解决本来很简单的问题。例如,你可以用一个命令行解决简单的问题,而C不行,即使一个再简单的程序,C语言也必须经过编写、编译的全过程。其次,awk本身是解释执行的,这就使得awk程序不必经过编译的过程,同时,这也使得它与shell script程序能够很好的契合。最后,awk本身较C语言简单,虽然awk吸收了C语言很多优秀的成分,熟悉C语言会对学习awk有很大的帮助,但awk本身不须要会使用C语言——一种功能强大但需要大量时间学习才能掌握其技巧的开发工具。

  使用awk的第三个理由是awk是一个容易获得的工具。与C和C++语言不同,awk只有一个文件(/bin/awk),而且几乎每个版本的UNIX都提供各自版本的awk,你完全不必费心去想如何获得awk。但C语言却不是这样,虽然C语言是UNIX天然的开发工具,但这个开发工具却是单独发行的,换言之,你必须为你的UNIX版本的C语言开发工具单独付费(当然使用D版者除外),获得并安装它,然后你才可以使用它。

  基于以上理由,再加上awk强大的功能,我们有理由说,如果你要处理与文本样式扫描相关的工作,awk应该是你的第一选择。在这里有一个可遵循的一般原则:如果你用普通的shell工具或shell script有困难的话,试试awk,如果awk仍不能解决问题,则便用C语言,如果C语言仍然失败,则移至C++。

  sed是一个非交互性文本流编辑器。它编辑文件或标准输入导出的文本拷贝。sed编辑器按照一次处理 一行的方式来处理文件(或者输入)并把输出送到屏幕上。你可以在vi和ex/ed编辑器里识别他的命令。sed把当前正在处理的行保存在一个临时缓存里,这个缓存叫做模式空间。一但sed完成了对模式空间里的行的处理(即对该行执行sed命令),就把模式空间的行送到屏幕上(除非该命令要删除该行活禁止打印)。处理完该行之后,从模式空间里删除它,然后把下一行读入模式空间,进行处理,并显示。当输入文件的最后一行处理完后,sed终止。通过把每一行存在一个临时缓存里并编辑该行,初始文件不会被修改或被破坏。

0

评论区