正则+grep+awk+sed

发布于:2025-03-26 ⋅ 阅读:(32) ⋅ 点赞:(0)

通配符 * ? {1..100} 在shell里 --》bash

* 代表任意个任意的字符串

? 代表单个任意字符串

在grep里代表什么意思呢? ---》正则表达式 --》元字符

正则表达式:使用一些特殊符号+字母和数字按照某个正确的规则组合成一个公式用来表达某个意思这就叫正则表达式

特殊符号: 元字符 作用: 用来描述其他字符的字符 ---》有特殊意义的字符

为了在表达某个意思的时候,少写字符,更加简洁的表达出来,而且还要表达更加丰富的含义。

转义元字符 : 就是\ 让有特殊符号的字符,回归到它最原始的含义,没有特殊作用。

正则表达式常见元字符及语法

单字符匹配

.(点号):匹配任意单个字符(除换行符 \n 外)。

示例:a.b 匹配 a 后面跟着任意字符,再跟着 b,如 a1b、a-b。

[abc](字符集):匹配方括号内的任意一个字符。

示例:[abc] 匹配 a 或 b 或 c。

[a-z](字符范围):匹配指定范围内的任意一个字符。

示例:[a-z] 匹配任意一个小写字母。

[^abc](否定字符集):匹配不在方括号内的任意一个字符。

示例:[^abc] 匹配除 a、b、c 之外的任意字符。

[123](数字集):匹配方括号内的任意一个数字。

示例:[123] 匹配 1或 2 或 3。

[0-9](数字范围):匹配方括号内的任意一个数字。

示例:[0-9] 匹配任意一个数字。

[0-Z](数字+字母):匹配方括号内的任意一个数字或字母(包括大小写)。

示例:[0-Z] 匹配任意一个数字或字母。

[^0-Z](数字+字母):匹配特殊字符(非数字或字母)。

示例:[^0-Z] 匹配任意一个非数字或字母。

重复匹配

*(星号):匹配前面的元素 0 次或多次。

示例:a* 匹配 0 个或多个 a,如 aa、a、空字符串。

+(加号):匹配前面的元素 1 次或多次。

示例:a+ 匹配 1 个或多个 a,如 aa、a,但不匹配空字符串。

?(问号):匹配前面的元素 0 次或 1 次。

示例:a? 匹配 0 个或 1 个 a,如 a、空字符串。

{n}(精确匹配):匹配前面的元素恰好 n 次。

示例:a{3} 匹配恰好 3 个 a,如 aaa。

{n,}(至少匹配):匹配前面的元素至少 n 次。

示例:a{2,} 匹配 2 个或更多 a,如 aa、aaa。

{n,m}(范围匹配):匹配前面的元素 n 到 m 次。

示例:a{1,3} 匹配 1 到 3 个 a,如 a、aa、aaa。

位置匹配

^(脱字符):匹配字符串的开头。

示例:^a 匹配以 a 开头的字符串,如 abc,但不匹配 bca。

$(美元符号):匹配字符串的结尾。

示例:a$ 匹配以 a 结尾的字符串,如 cba,但不匹配 abc。

\b(单词边界):匹配单词的边界。

示例:\bcat\b 匹配单词 cat,但不匹配 catalog。

\B(非单词边界):匹配非单词边界。

示例:\Bcat\B 匹配 catalog 中的 cat,但不匹配单独的单词 cat。

\<:匹配单词的开头。(字母、数字或下划线)

\>:匹配单词的结尾。(字母、数字或下划线)

分组与引用

()(圆括号):用于分组,可以对分组的内容进行整体匹配或引用。

示例:(ab)+ 匹配 ab 的多次重复,如 abab。

\1、\2 等(反向引用):引用前面分组匹配到的内容。

示例:(\d+)\.\1 匹配 123.123,其中 \1 引用了第一个分组的内容。

选择与逻辑

|(竖线):表示选择,匹配多个模式中的任意一个。

示例:a|b匹配 a或 b。

特殊字符

\d:匹配任意数字(等价于 [0-9])。grep -P '\d'

\D:匹配任意非数字(等价于 [^0-9])。grep -P '\D'

\w:匹配任意字母或数字或下划线(等价于 [a-zA-Z0-9_])。grep '\w'

\W:匹配任意非字母数字下划线(等价于 [^a-zA-Z0-9_])。grep '\W'

\s:匹配任意空白字符(空格、制表符、换行符等)。grep '\s'

\S:匹配任意非空白字符。grep '\S'

grep

常用选项

1. -i(忽略大小写)

功能:忽略大小写差异,进行大小写不敏感的匹配。

示例:grep -i "hello" file.txt

匹配 "hello"、"Hello"、"HELLO" 等。

2. -v(反向匹配)

功能:反向匹配,显示不包含指定模式的行。

示例:grep -v "hello" file.txt

显示不包含 "hello" 的行。

3. -n(显示行号)

功能:在匹配的行前显示行号。

示例:grep -n "hello" file.txt

输出匹配行及其行号。

4. -c(计数)

功能:统计匹配的行数,而不是显示匹配的行。

示例:grep -c "hello" file.txt

输出匹配 "hello" 的行数。

5. -l(显示文件名)

功能:只显示包含匹配模式的文件名,而不是显示匹配的行。

示例:grep -l "hello" file1.txt file2.txt

输出包含 "hello" 的文件名。

6. -L(显示不包含模式的文件名)

功能:只显示不包含匹配模式的文件名。

示例:grep -L "hello" file1.txt file2.txt

输出不包含 "hello" 的文件名。

7. -E(扩展正则表达式)==egrep

功能:启用扩展正则表达式(ERE),支持更多的元字符和功能。

示例:grep -E 'a+' file.txt

匹配包含一个或多个 'a' 的行。

8. -w(匹配整个单词)

功能:只匹配整个单词,相当于在模式前后加上单词边界 \b。

示例:grep -w "hello" file.txt

匹配 "hello",但不匹配 "hello123"。

9. -A(显示匹配行之后的行)

功能:在匹配行之后显示指定数量的行。

语法:grep -A <number> <pattern> <file>

示例:grep -A 2 "hello" file.txt

显示匹配 "hello" 的行及其后的两行。

10. -B(显示匹配行之前的行)

功能:在匹配行之前显示指定数量的行。

语法:grep -B <number> <pattern> <file>

示例:grep -B 2 "hello" file.txt

显示匹配 "hello" 的行及其前的两行。

11. -C(显示匹配行的上下文)

功能:在匹配行的前后各显示指定数量的行。

语法:grep -C <number> <pattern> <file>

示例:grep -C 2 "hello" file.txt

显示匹配 "hello" 的行及其前后的两行。

12.-r(递归搜索)

功能:递归地搜指定目录下的所有文件,包括子目录中的文件。

语法:grep -r <pattern> <directory>

示例:grep -r "hello" /path/to/directory

在 /path/to/directory 目录及其子目录中递归搜索包含 "hello" 的行。

13. -o(仅匹配)

功能:仅输出匹配的部分,而不是整行。

语法:grep -o <pattern> <file>

示例:grep -o "hello" file.txt

仅输出文件 file.txt 中匹配 "hello" 的部分。

cat /etc/ssh/sshd_config |egrep -v "^#|^$|^\s" --》过滤掉注释行和空行

cat /etc/ssh/sshd_config |egrep -v "^#|^$|^\s+#" --》防止注释行不是从第一个字符开始

修改字段
awk '{ $2 = "new_value"; print $0 }' file.txt  # 修改第二列并打印整行
awk '{ $3 = $1 + $2; print $0 }' file.txt      # 将第三列设置为第一列和第二列的和
多条件组合
awk '$1 > 10 && $2 < 20 { print $0 }' file.txt  # 第一列大于 10 且第二列小于 20
awk '$1 == "foo" || $2 == "bar" { print $0 }' file.txt # 第一列是 "foo" 或第二列是 "bar"

4. 示例

示例文件 file.txt
Alice 25 Engineer
Bob 30 Doctor
Charlie 35 Teacher
David 40 Lawyer
示例命令
  1. 打印所有行:
awk '{ print $0 }' file.txt
  1. 打印第一列和第三列:
awk '{ print $1, $3 }' file.txt
  1. 打印年龄大于 30 的行:
awk '$2 > 30 { print $0 }' file.txt
  1. 打印以 "C" 开头的行:
awk '/^C/ { print $0 }' file.txt
  1. 计算平均年龄:
awk '{ sum += $2 } END { print "Average age:", sum / NR }' file.txt

5. 高级用法

自定义函数
awk '
function my_function(x) {
    return x * 2
}
{ print my_function($1) }
' file.txt
多文件处理
awk '{ print FILENAME, $0 }' file1.txt file2.txt
使用数组
awk '{ names[NR] = $1 } END { for (i in names) print names[i] }' file.txt

6. 常用选项

选项

描述

-F

指定输入字段分隔符。

-v

定义变量。

-f

从脚本文件中读取 awk命令。

sed

1. 基本语法

sed [options] 'command' input_file
  • options:选项,控制 sed 的行为。
  • command:要执行的命令。
  • input_file:输入文件。如果省略,则从标准输入读取。

2. 常用选项

选项

描述

-n

抑制默认输出,只打印被 p命令处理的行。

-e

指定多个命令。

-f

从文件中读取 sed命令。

-i

直接修改文件内容(慎用,会覆盖原文件)。

-r

使用扩展正则表达式(类似 egrep)。

3. 常用命令

替换命令 s
sed 's/pattern/replacement/' input_file        # 替换每行第一个匹配的 "pattern"
sed 's/pattern/replacement/g' input_file      # 替换每行所有匹配的 "pattern"
sed 's/pattern/replacement/2' input_file      # 替换每行第二个匹配的 "pattern"
sed 's/pattern/replacement/i' input_file      # 忽略大小写替换
删除命令 d
sed '/pattern/d' input_file                   # 删除包含 "pattern" 的行
sed '1d' input_file                           # 删除第一行
sed '$d' input_file                           # 删除最后一行
sed '1,5d' input_file                         # 删除第 1 到第 5 行
打印命令 p
sed -n '/pattern/p' input_file               # 只打印包含 "pattern" 的行
sed -n '1p' input_file                       # 只打印第一行
sed -n '1,5p' input_file                     # 只打印第 1 到第 5 行
插入命令 i 和追加命令 a
sed '2i\New Line' input_file                 # 在第二行之前插入 "New Line"
sed '/pattern/i\New Line' input_file         # 在包含 "pattern" 的行之前插入 "New Line"
sed '2a\New Line' input_file                 # 在第二行之后追加 "New Line"
sed '/pattern/a\New Line' input_file         # 在包含 "pattern" 的行之后追加 "New Line"
替换行命令 c
sed '/pattern/c\New Line' input_file         # 将包含 "pattern" 的行替换为 "New Line"
sed '2c\New Line' input_file                 # 将第二行替换为 "New Line"
读取文件命令 r
sed '/pattern/r file_to_insert' input_file   # 在包含 "pattern" 的行后插入文件内容
写入文件命令 w
sed '/pattern/w output_file' input_file     # 将包含 "pattern" 的行写入到输出文件
退出命令 q
sed '5q' input_file                         # 处理到第 5 行后退出
sed '/pattern/q' input_file                 # 处理到包含 "pattern" 的行后退出

4. 示例

示例文件 file.txt
Alice 25 Engineer
Bob 30 Doctor
Charlie 35 Teacher
David 40 Lawyer
示例命令
  1. 替换 "Engineer" 为 "Developer":
sed 's/Engineer/Developer/' file.txt
  1. 删除包含 "Doctor" 的行:
sed '/Doctor/d' file.txt
  1. 打印第 2 行:
sed -n '2p' file.txt
  1. 在第二行之前插入 "New Line":
sed '2i\New Line' file.txt
  1. 将第三行替换为 "New Line":
sed '3c\New Line' file.txt
  1. 将文件内容直接修改(替换 "Alice" 为 "Eve"):
sed -i 's/Alice/Eve/' file.txt

5. 高级用法

多命令组合

使用 -e 选项执行多个命令:

sed -e 's/Alice/Eve/' -e 's/Doctor/Physician/' file.txt
使用正则表达式
sed 's/[0-9]\+/AGE/' file.txt                # 将所有数字替换为 "AGE"
sed '/^C/ s/Teacher/Mentor/' file.txt        # 将以 "C" 开头的行中的 "Teacher" 替换为 "Mentor"
使用变量
pattern="Alice"
replacement="Eve"
sed "s/$pattern/$replacement/" file.txt
处理特定范围的行
sed '2,4s/ / - /' file.txt                   # 将第 2 到第 4 行中的空格替换为 " - "

6. 常用场景

删除空行
sed '/^$/d' file.txt
删除行首和行尾的空格
sed 's/^ *//;s/ *$//' file.txt
将 DOS 换行符(\r\n)转换为 Unix 换行符(\n
sed 's/\r//' file.txt
将文件中的单词转换为大写
sed 's/.*/\U&/' file.txt

练习-grep

1.进入/lianxi目录,复制/etc/passwd到当前目录下,然后对passwd进行操作

2、查找出当前passwd文件中以ftp或者mail开头的行,在屏幕上输出。

3、查找出当前passwd文件中首行不是以r、m、f开头的行,在屏幕上输出。

4、查找出当前passwd文件中以bash结尾的行。

5、查找出/etc/login.defs文件中的有效行(不显示空行和注释行)。

6、查找出/var/log/messages文档中有16个字母的单词?

7、查找出来/etc/passwd文件里用户名包含liu同时使用bash的用户

8、查找/etc/ssh/sshd_config 里的有效行

9、查找出/etc/ssh/sshd_config 文件里的包含连续2个数字的行

10、查找出包含特殊字符的行

11、查找出不包含数字的行

12、查找出/var/log/secure里的ip地址出来

13、写一个表示下面网址的正则表达式出来--》egrep -o "[a-Z]+://[0-Z]+\.[0-Z]+(\.[0-Z]+)+" url.txt

百度一下,你就知道

home.sina.com

网易

中国铁路12306网站

http://www.qillu.edu

rsync://www.github.com/abc

ftp://192.168.0.1

ftp://www.baidu.com

14、写一个表示邮箱的正则--》egrep -o "[0-Z_]+@[0-Z]+\.[0-Z]+" mail.txt

feng@qq.com

1234feng@163.com

meng.xianhui@yahoo.cn

liudehua@sina.com

10001@qq.com

123_ui@12306.cn

qilu@qilu.edu

qilu@qilu.edu/fjdkfjk/fjdk

15、C类ip地址的正则表达式

section1:范围在192-223之间

section2和section3和section4范围:0-255之间

例如:193.168.23.1

练习--awk

1.获取cpu使用率最高的前5个进程的 pid %cpu command name ,按照降序排列

ps -eo pid,%cpu,command --sort=-%cpu|head

2.获取内存使用率最高的前5个进程的 pid %mem command name ,按照降序排列

ps -eo pid,%mem,command --sort=-%mem|head

3.只显示df -h结果的第一列文件系统

4.显示passwd文件的第5行和第10行的行号和用户名

awk -F: 'NR==5 || NR==10 {print NR,$1}' /etc/passwd

5.使用NF变量显示passwd文件倒数第二列的内容

6.显示passwd文件中第5到第10行的用户名

7.显示passwd文件中第7列不是bash的用户名

8.显示passwd文件中行号是5结尾的行号和行

awk -F: 'NR ~ /5$/ {print NR,$0}' /etc/passwd

9.用ip add只显示ip

ip add|tr -s " "|awk -F"[ /]" '/ens33$/{print $3}'

(不使用tr或者cut命令)

ip add|awk -F"[ /]" '/ens33$/{print $6}'

10.使用awk显示ens33的入站流量和出站流量(字节)

yum install net-tools -y

ifconfig

ifconfig|awk 'NR==5||NR==7{print $1,$5}'

11.使用awk命令统计以r开头的用户数目

awk -F: '/^r/{print $1;num++}END{print num}' /etc/passwd

练习--sed

cd /lianxi

1.复制/root/.bash_profile文件到当前目录下,然后修改里面的PATH变量,修改为PATH=/sanchuang/bin:$PATH

2.sed修改SELINUX配置文件从开启(enforcing)变成禁用(disabled)

cp /etc/sysconfig/selinux .

3.复制/etc/sysconfig/network-scripts/ifcfg-ens33到当前目录下,将当前下的ifcfg-ens33里的BOOTPROTO="dhcp" 修改为BOOTPROTO="none"

cp /etc/sysconfig/network-scripts/ifcfg-ens33 .

然后再修改,添加下面的行

IPADDR=192.168.34.1

GATEWAY=192.168.34.254

PREFIX=24

DNS1=114.114.114.114

4.复制/etc/ssh/sshd_config到当前目录下,修改里面的端口号修改为8899

将#Port 22 配置修改为Port 8899 要求去掉前面的#号,将22修改为8899

cp /etc/ssh/sshd_config .

注意:所有的文件建议复制到当前目录下操作,不然重新启动系统会导致系统启动不起来。