正则表达式-“三剑客”(grep、sed、awk)

1.3正则表达式

正则表达式描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串,将匹配的子串替换或者从某个串中取出符号某个条件的子串等,在linux中代表自定义的模式模版,linux工具可以用正则表达式过滤文本。Linux工具能够在处理数据时使用正则表达式对数据进行模式匹配,如果数据符合匹配的要求,那么就会进入下一步处理,如果数据不符合匹配的要求,就会被过滤掉

1.3.1 grep命令

grep(global regular expression print):表示全局正则表达式,使用权限是所有用户,grep命令是文本搜集工具,能够使用正则表达式搜索文本,并把匹配的行打印出来

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -m 匹配几次后停止 -v 反选 -i 忽略字符大小写 -n 显示匹配行号 -c 统计匹配行数 -o 仅显示匹配到的字符串 -q 静默模式 -A 后几行 -B 前几行 -C 前后各几行 -e 多个选项之间"或者"关系 -w 匹配整个单词 -E 启用扩展正则表达式=egrep -F 不支持正则表达式=fgrep -f 处理两个文件的相同内容,以第一个文件作为匹配条件 -r 递归,但不处理软链接 -R 递归,处理软链接 |

示例:A、B、C用法

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| #打印包含halt的行以及下面三行 root@localhost \~# grep -A3 "halt" /etc/passwd halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin #打印包含halt的行以及上面三行 root@localhost \~# grep -B3 "halt" /etc/passwd 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 #打印包含halt的行以及上下面三行 root@localhost \~# grep -C3 "halt" /etc/passwd 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 operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin |

过滤出带有某个关键词的行,并输出行号

|-------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# grep -n "root" /etc/passwd 1:root:x:0:0:root:/root:/bin/bash 10:operator:x:11:0:operator:/root:/sbin/nologin |

过滤出不带有某个关键词的行,并输出行号

过滤出所有包含数字的行

|---------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# grep "0-9" /etc/inittab # multi-user.target: analogous to runlevel 3 # graphical.target: analogous to runlevel 5 |

过滤掉所有以#开头的行

过滤掉所有空行和以#开头的行

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost etc# grep -v "^#" /etc/fstab |grep -v "^$" /dev/mapper/centos-root / xfs defaults 0 0 UUID=ee382caa-3a27-4985-a6a0-2920648fe4f4 /boot xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0 |

在正则表达式中,^表示行的开始,表示行的结尾,那么空行则可以用\^表示

过滤出任意一个字符和重复字符

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# grep "r.o" /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin .表示任意一个字符,上例中,r.o表示把r与o之间有一个任意字符的行过滤出来 root@localhost \~# grep "ooo*" /etc/passwd root:x:0:0:root:/root:/bin/bash lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin *表示零个或多个*前面的字符,上例中,ooo*表示oo、ooo、oooo.....或者更多的 root@localhost \~# grep ".*" /etc/passwd |wc -l 19 root@localhost \~# wc -l /etc/passwd 19 /etc/passwd *表示零个或多个*前面的字符,空行也包含在内,它会把/etc/passwd文件里面的所有行都匹配到 |

指定要过滤出的字符出现次数

1.3.2 sed命令

sed编辑器是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流

sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| s 替换,替换指定字符 d 删除,删除选定的行 a 增加,在当前行下面增加一行指定内容 i 插入,在选定行上面插入一行指定内容 c 替换,将选定行替换为指定内容 Y 字符转换,转换前后的字符长度必须相同 p 打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以ASCII码输出。其通常与"-n"选项一起使用 = 打印行号 l 打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\t) |

打印某行

|---------------------------------------------------------------------------------|
| root@localhost \~# sed -n '2'p /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin |

打印所有行

打印某个区间内的行数

|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# sed -n '1,3'p /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 |

打印包含某个字符串的行

|----------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# sed -n '/root/'p /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin |

删除某些行

|---------------------------------------------|
| root@localhost \~# sed '1'd /etc/passwd |

1.3.3 awk命令

awk是一种处理文本文件的语言,是一个强大的文本分析工具,可以在无交互的模式下实现复杂的文本操作,相较于sed常作用于一整个行的处理,awk则比较倾向于一行当中分成数个字段来处理,因为awk相当适合小型的文本数据

awk格式及原理

awk命令逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。sed命令常用于一整行的处理,而awk比较倾向于将一行分成多个"字段"然后再进行处理,awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| FS 列分隔符,指定每行文本的字段分隔符,默认为空格或制表位,与-F作用相同 NF 当前处理的行的字段个数 NR 当前处理的行的行号(序数) 0 当前处理的行的整行内容 n 当前处理行的第n个字段(第n列) FILENAME 被处理的文件名 RS 行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录,而awk一次仅读入一条记录,以进行处理。预设值是'\n' NF 最后一段 (NF-1) 倒数第二段 |

截取文档中的某个段

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# head -n2 test.txt |awk -F ':' '{print 1}' root Bin 解析: Awk是一个强大的文本处理工具 -F':':选项指定字段分隔符为冒号 {print 1}:表示打印每行的第一个字段 root@localhost \~# head -n2 test.txt |awk -F ':' '{print $0}' root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin |

匹配字符或者字符串

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# awk '/oo/' test.txt root:x:0:0:root:/root:/bin/bash lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin root@localhost \~# awk -F ':' '$1 ~/oo/' test.txt root:x:0:0:root:/root:/bin/bash |

条件操作符

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# awk -F ':' '3=="0"' /etc/passwd \[root@localhost \~\]# awk -F ':' '3>="500"' /etc/passwd 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 nobody:x:99:99:Nobody:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin chrony:x:998:996::/var/lib/chrony:/sbin/nologin root@localhost \~# awk -F ':' '$3>=500' /etc/passwd polkitd:x:999:998:User for polkitd:/:/sbin/nologin chrony:x:998:996::/var/lib/chrony:/sbin/nologin |

awk的内置变量

awk常用的变量有OFS、NF和NR,OFS和-F选项有类似的功能,也是用来定义分隔符的,但是他是在输出的时候定义,NF表示用分隔符分隔后一共有多少段,NR表示行号

OFS的用法示例如下:

|---------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# head -5 /etc/passwd |awk -F ':' '{OFS="#"} {print 1,3,$4}' root#0#0 bin#1#1 daemon#2#2 adm#3#4 lp#4#7 |

变量NF的具体用法如下:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# head -n3 /etc/passwd |awk -F ':' '{print NF}' 7 7 7 root@localhost \~# head -n3 /etc/passwd |awk -F ':' '{print $NF}' /bin/bash /sbin/nologin /sbin/nologin |

变量NR的具体用法如下

|-----------------------------------------------------------------------------|
| root@localhost \~# head -n3 /etc/passwd |awk -F ':' '{print NR}' 1 2 3 |

还可以使用NR作为判断条件,如下所示

awk中的数学运算,示例命令如下

awk可以更改段值,示例命令如下

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# head -n 3 /etc/passwd |awk -F ':' '$1="root"' root x 0 0 root /root /bin/bash root x 1 1 bin /bin /sbin/nologin root x 2 2 daemon /sbin /sbin/nologin |

awk也可以进行对各个段的值进行数学运算,示例命令如下

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@localhost \~# head -n2 /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin root@localhost \~# head -n2 /etc/passwd |awk -F ':' '{7=4+3}' \[root@localhost \~\]# head -n2 /etc/passwd \|awk -F ':' '{7=4+3;print $0}' root x 0 0 root /root 0 bin x 1 1 bin /bin 2 |

awk还可以计算某个段的总和,实力命令如下

|--------------------------------------------------------------------------------------|
| root@localhost \~# awk -F ':' '{(tot=tot+$3)}; END {print tot}' /etc/passwd 2605 |

这里的END是awk特有的语法,表示所有的行都已经执行。

|--------------------------------------------------------------------------------------------------------------|
| root@localhost \~# awk -F ':' '{if (1=="root") {print 0}}' /etc/passwd root:x:0:0:root:/root:/bin/bash |

相关推荐
A小辣椒9 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒13 小时前
TShark:基础知识
linux
AlfredZhao15 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334661 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5202 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩2 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言