Shell正则表达式与文本处理三剑客(grep、sed、awk)

news2025/1/18 15:30:23

一、正则表达式

Shell正则表达式分为两种:

基础正则表达式:BRE(basic regular express)

扩展正则表达式:ERE(extend regular express),扩展的表达式有+、?、|和()

1.1 基本正则表达式

1.2 扩展正则表达式

1.3 支持正则表达式的工具

grep:默认不支持扩展表达式,加-E选项开启ERE。如果不加-E使用花括号要加转义符\{\}

egrep:支持基础和扩展表达式

awk:支持egrep所有的正则表达式

sed:默认不支持扩展表达式,加-r选项开启ERE。如果不加-r使用花括号要加转义符\{\}

二、grep

过滤来自一个文件或标准输入匹配模式内容。

除此之外还有:

grep -f:从文件每一行获取匹配模式

grep -m:输出匹配的结果num数

grep -H:打印每个匹配的文件名

grep -h:不输出文件名

grep -q:不输出正常信息

grep -s:不输出错误信息

grep -r:递归目录

grep -B:打印匹配的前几行

grep -A:打印匹配的后几行

grep -C:打印匹配的前后几行

grep --color:匹配的字体颜色

(1)输出b文件在a文件相同的行

> grep -f a b

(2)输出b文件在a文件不同的行

> grep -v -f a b 

(3)匹配多个模式

> echo "a bc de" |xargs -n1 |grep -e 'a' -e 'bc' 
a 
bc 

注:xargs为多行输出,-n1表示一行输出1个参数

(4)去除文件内的空行和#开头的行(一般用于查看配置文件)

> grep -E -v "^$|.*#" /etc/httpd/conf/httpd.conf

(5)匹配开头不分大小写的单词

> echo "A a b c" |xargs -n1 |grep -i a
A
a

(6)只显示匹配的字符串

> echo "this is a test" |grep -o 'is' 
is
is

(7)输出匹配的前五个结果

> seq 1 20 |grep -m 5 -E '[0-9]{2}' 
10 
11 
12 
13 
14

 (8)统计匹配多少行

> seq 1 20 |grep -c -E '[0-9]{2}' 
11

(9)匹配b字符开头的行

> echo "a bc de" |xargs -n1 |grep '^b'
bc

(10)匹配de字符结尾的行并输出匹配的行

> echo "a ab abc abcd abcde" |xargs -n1 |grep -n 'de$' 
5:abcde 

(11)递归搜索/etc目录下包含ip的conf后缀文件

grep --include:只检索匹配的文件

> grep -r '192.167.1.1' /etc --include *.conf 

(12)排除搜索bak后缀的文件

grep --exclude:跳过匹配的文件

> grep -r '192.167.1.1' /opt --exclude *.bak 

(13)匹配所有IP

> ifconfig |grep -E -o "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" 

(14)打印匹配结果及后3行

> seq 1 10 |grep 5 -A 3 
5 
6 
7 
8

(15)打印匹配结果及前3行

> seq 1 10 |grep 5 -B 3 
2 
3 
4

(16)打印匹配结果及前后3行

> seq 1 10 |grep 5 -C 3 
2 
3 
4 
5 
6 
7 
8 

三、sed

流编辑器,过滤和替换文本。

工作原理:sed命令将当前处理的行读入模式空间进行处理,处理完把结果输出,并清空模式空间。然后再将下一行读入模式空间进行处理输出,以此类推,直到最后一行。还有一个空间叫保持空间,又称暂存空间,可以暂时存放一些处理的数据,但不能直接输出,只能放到模式空间输出。

这两个空间其实就是在内存中初始化的一个内存区域,存放正在处理的数据和临时存放的数据。

语法格式:sed [选项] '地址 命令' file

借助一些文本内容作为示例:

[root@openEuler-1 script]# cat sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
blp5              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

3.1 匹配打印(p)

(1)打印匹配blp5开头的行

[root@openEuler-1 script]# sed -n '/^blp5/p' sed.txt
blp5              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator

(2)打印第一行

[root@openEuler-1 script]# sed -n '1p' sed.txt
nimgtw            48003/udp            # Nimbus Gateway

(3)打印第一行至第三行

[root@openEuler-1 script]# sed -n '1,3p' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services

(4)打印奇数行

[root@openEuler-1 script]# seq 10 | sed -n '1~2p'
1
3
5
7
9

(5)打印匹配行及后一行

[root@openEuler-1 script]# sed -n '/blp5/,+1p' sed.txt
blp5              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator

(6)打印最后一行

[root@openEuler-1 script]# sed -n '$p' sed.txt
iqobject          48619/udp            # iqobject

(7)不打印最后一行

感叹号也就是对后面的命令取反。

[root@openEuler-1 script]# sed -n '$!p' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
blp5              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject

(8)匹配范围blp5开头的行~com开头的行

以逗号分开两个样式选择某个范围。

[root@openEuler-1 script]# sed -n '/^blp5/,/^com/p' sed.txt
blp5              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw

3.2 匹配删除(d)

删除与打印使用方法类似,打印是把匹配的打印出来,删除是把匹配的删除,删除只是不用-n选项。

(1)删除包含blp5的行

[root@openEuler-1 script]# sed '/^blp5/d' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

(2)删除1~3行

[root@openEuler-1 script]# sed '1,3d' sed.txt
isnetserv         48128/udp            # Image Systems Network Services
blp5              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

(3)去除http.conf文件空行和开头#号的行

[root@openEuler-1 script]# sed '/^$/d;/.*#/d' /etc/httpd/conf/httpd.conf

3.3 替换(s///)

(1)替换blp5字符串为test

[root@openEuler-1 script]# sed 's/blp5/test/' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
test              48129/tcp            # Bloomberg locator
test              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

(2)替换开头是blp5的字符串并打印

[root@openEuler-1 script]# sed -n 's/blp5/test/p' sed.txt
test              48129/tcp            # Bloomberg locator
test              48129/udp            # Bloomberg locator

(3)使用&命令引用匹配内容并替换

[root@openEuler-1 script]# sed 's/48049/&.0/' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049.0/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
blp5              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

(4)给IP加引号

g:全局替换

[root@openEuler-1 script]# echo "192.168.121.11 172.1.1.2 223.5.5.5" | sed -r 's/[^ ]+/“&”/g'
“192.168.121.11” “172.1.1.2” “223.5.5.5”

(5)对1-5行的blp5进行替换

[root@openEuler-1 script]# sed '1,5s/blp5/test/' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
test              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

(6)对匹配行进行替换

[root@openEuler-1 script]# sed '/48129\/tcp/s/blp5/test/' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
test              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

(7)二次匹配替换

[root@openEuler-1 script]# sed 's/blp5/test/;s/3g/4g/' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
4gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
test              48129/tcp            # Bloomberg locator
test              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

(8)注释匹配行后的多少行

[root@openEuler-1 script]# seq 10 | sed '/5/,+3s/^/#/'
1
2
3
4
#5
#6
#7
#8
9
10

3.4 多重编辑(-e)

[root@openEuler-1 script]# sed -e '1,2d' -e 's/blp5/test/' sed.txt
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
test              48129/tcp            # Bloomberg locator
test              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

# 也可以使用;分隔
[root@openEuler-1 script]# sed '1,2d;s/blp5/test/' sed.txt
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
test              48129/tcp            # Bloomberg locator
test              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

3.5 添加新内容(a,i、c)

(1)在blp5上一行添加test

[root@openEuler-1 script]# sed '/blp5/i \test' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
test
blp5              48129/tcp            # Bloomberg locator
test
blp5              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

(2)在blp5下一行添加test

[root@openEuler-1 script]# sed '/blp5/a \test' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
blp5              48129/tcp            # Bloomberg locator
test
blp5              48129/udp            # Bloomberg locator
test
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

(3)将blp5替换新行

[root@openEuler-1 script]# sed '/blp5/c \test' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
test
test
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

3.6 读取文件并追加到匹配行后(r)

[root@openEuler-1 script]# cat a.txt
123
456
[root@openEuler-1 script]# sed '/blp5/r a.txt' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
blp5              48129/tcp            # Bloomberg locator
123
456
blp5              48129/udp            # Bloomberg locator
123
456
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject

3.7 将匹配行写入文件(w)

[root@openEuler-1 script]# sed '/blp5/w b.txt' sed.txt
nimgtw            48003/udp            # Nimbus Gateway
3gpp-cbsp         48049/tcp            # 3GPP Cell Broadcast Service Protocol
isnetserv         48128/tcp            # Image Systems Network Services
isnetserv         48128/udp            # Image Systems Network Services
blp5              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator
com-bardac-dw     48556/tcp            # com-bardac-dw
com-bardac-dw     48556/udp            # com-bardac-dw
iqobject          48619/tcp            # iqobject
iqobject          48619/udp            # iqobject
[root@openEuler-1 script]# cat b.txt
blp5              48129/tcp            # Bloomberg locator
blp5              48129/udp            # Bloomberg locator

3.8 读取下一行(n和N)

n 读取下一行到模式空间。

N 追加下一行内容到模式空间,并以换行符\n分隔。

(1)打印匹配的下一行

[root@openEuler-1 script]# seq 5 |sed -n '/3/{n;p}'
4

(2)打印偶数

[root@openEuler-1 script]# seq 10 | sed -n 'n;p'
2
4
6
8
10
# sed先读取第一行1,执行n命令,获取下一行2,此时模式空间是2,
# 执行p命令,打印模式空间。 现在模式空间是2,sed再读取3,
# 执行n命令,获取下一行4,此时模式空间为4,执行p命令,以此类推.

(3)打印奇数

[root@openEuler-1 script]# seq 10 |sed 'n;d'
1
3
5
7
9
# sed先读取第一行1,此时模式空间是1,并打印模式空间1,
# 执行n命令,获取下一行2,执行d命令,删除模式空间的2,sed再读取3,
# 此时模式空间是3,并打印模式空间,再执行n命令,获取下一行4,
# 执行d命令,删除模式空间的3,以此类推.

3.9 打印和删除模式空间的第一行(P和D)

P 打印模式空间的第一行。

D 删除模式空间的第一行。

(1)打印奇数

[root@openEuler-1 script]# seq 6 | sed -n 'N;P'
1
3
5

(2)保留最后一行

[root@openEuler-1 script]# seq 6 | sed 'N;D'
6
# 读取第一行1,执行N命令读取下一行并追加到模式空间,
# 此时模式空间是1\n2,执行D命令删除模式空间第一行1,剩余2.
# 读取第二行,执行N命令,此时模式空间是3\n4,
# 执行D命令删除模式空间第一行3,剩余4,以此类推.

3.10 保持空间操作(h与H、g与G和x)

h 复制模式空间内容到保持空间(覆盖)。

H 复制模式空间内容追加到保持空间。

g 复制保持空间内容到模式空间(覆盖)。

G 复制保持空间内容追加到模式空间。

x 模式空间与保持空间内容互换。

(1)将匹配的内容覆盖到另一个匹配

[root@openEuler-1 script]# seq 6 | sed -e '/3/{h;d}' -e '/5/g'
1
2
4
3
6
# h命令把匹配的3复制到保持空间,d命令删除模式空间的3.
# 后面命令再对模式空间匹配5,并用g命令把保持空间3覆盖模式空间5.

(2)将匹配的内容放到最后

[root@openEuler-1 script]# seq 6 | sed -e '/3/{h;d}' -e '$G'
1
2
4
5
6
3
# 这里的$代表最后一行,G表示将保持空间的内容追加到当前行的后面

(3)交换模式空间和保持空间

[root@openEuler-1 script]# seq 6 | sed -e '/3/{h;d}' -e '/5/x' -e '$G'
1
2
4
3
6
5
# 在模式空间匹配5并将保持空间的3与5交换,5就变成了3.
# 最后把保持空间的5追加到模式空间. 

(4)倒序输出

[root@openEuler-1 script]# seq 5 |sed '1!G;h;$!d'
5
4
3
2
1
# 1!G 第一行不执行把保持空间内容追加到模式空间,因为现在保持空间还没有数据
# h 将模式空间放到保持空间暂存
# $!d 最后一行不执行删除模式空间的内容。

(5)每行后面添加新空行

[root@openEuler-1 script]# seq 5 |sed G
1

2

3

4

5

3.11 忽略大小写匹配(I)

[root@openEuler-1 script]#  echo -e "a\nA\nb\nc" |sed 's/a/1/Ig'
1
1
b
c

3.12 获取总行数

[root@openEuler-1 script]# seq 10 |sed -n '$='
10

四、awk

awk 是一个处理文本的编程语言工具,能用简短的程序处理标准输入或文件、数据排序、计算以及 生成报表等。

基本的命令语法:awk option 'pattern {action}' file

其中pattern表示AWK在数据中查找的内容,而action是在找到匹配内容时所执行的一系列命令。花括号用于根据特定的模式对一系列指令进行分组。

awk 处理的工作方式与数据库类似,支持对记录和字段处理,这也是grep和sed不能实现的。在awk中,缺省的情况下将文本文件中的一行视为一个记录,逐行放到内存中处理,而将一行中的某一部分作为记录中的一个字段。用1,2,3...数字的方式顺序的表示行(记录)中的不同字段。用$后跟数字,引用对应的字段,以逗号分隔,0表示整个行。

4.1 选项、模式

(1)从文件读取awk程序处理文件

[root@openEuler-1 script]# cat test.awk
{print $2}
[root@openEuler-1 script]# tail -n3 /etc/services | awk -f test.awk
45514/udp
45514/tcp
46998/tcp

(2)指定分隔符,打印指定字段(默认以空格分割)

[root@openEuler-1 script]# tail -n3 /etc/passwd | awk -F':' '{print $1}'
apache
mysql
nginx

(3)指定多个分隔符作为同一个分隔符处理

[root@openEuler-1 script]# tail -n3 /etc/services
cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
spremotetablet  46998/tcp               # Capture handwritten signatures

[root@openEuler-1 script]# tail -n3 /etc/services | awk -F'[/#]' '{print $1}'
cloudcheck-ping 45514
cloudcheck      45514
spremotetablet  46998
[root@openEuler-1 script]# tail -n3 /etc/services | awk -F'[/#]' '{print $2}'
udp
tcp
tcp
[root@openEuler-1 script]# tail -n3 /etc/services | awk -F'[/#]' '{print $3}'
 ASSIA CloudCheck WiFi Management keepalive
 ASSIA CloudCheck WiFi Management System
 Capture handwritten signatures

(4)变量赋值

[root@openEuler-1 script]# awk -v a=123 'BEGIN{print a}'
123

(5)输出awk全局变量到文件

[root@openEuler-1 script]# seq 5 | awk --dump-variables '{print $0}'
1
2
3
4
5
[root@openEuler-1 script]# cat awkvars.out
ARGC: 1
ARGIND: 0
ARGV: array, 1 elements
BINMODE: 0
CONVFMT: "%.6g"
ENVIRON: array, 25 elements
ERRNO: ""
FIELDWIDTHS: ""
FILENAME: "-"
FNR: 5
FPAT: "[^[:space:]]+"
FS: " "
FUNCTAB: array, 41 elements
IGNORECASE: 0
LINT: 0
NF: 1
NR: 5
OFMT: "%.6g"
OFS: " "
ORS: "\n"
PREC: 53
PROCINFO: array, 21 elements
RLENGTH: 0
ROUNDMODE: "N"
RS: "\n"
RSTART: 0
RT: "\n"
SUBSEP: "\034"
SYMTAB: array, 28 elements
TEXTDOMAIN: "messages"

(6)BEGIN和END

BEGIN模式是在处理文件之前执行该操作,常用于修改内置变量、变量赋值和打印输出的页眉或标 题。END模式是在程序处理完才会执行。

示例:

[root@openEuler-1 script]# cat frequent_ip.sh
#!/bin/bash
#########################
#File name:frequent_ip.sh
#Email:obboda@163.com
#Created time:2025-01-14 11:46:11
#Description:访问nginx日志,得到访问ip最多的前10个
#########################

log_path="/var/log/nginx/access.log"

# 拿取按照访问次数排序过的ip
sort_data=`awk  '{print $1}'  /var/log/nginx/access.log | sort | uniq -c`


# 按照sort_data的数据进行优化处理,打印输出
echo "$sort_data" | awk '
BEGIN{printf "%-10s %-10s %-10s \n","访问排名","访问IP","访问次数"}
{printf "%-10s %-20s %-10s \n",NR,$2,$1}
END{print "end............"}
'
[root@openEuler-1 script]# bash frequent_ip.sh
访问排名       访问IP       访问次数
1          192.168.121.1        8
2          192.168.121.12       3
3          192.168.121.13       2
4          192.168.121.131      1
5          192.168.121.51       4
end............

4.2 内置变量

(1)FS和OFS

在程序开始前重新赋值FS变量,改变默认分隔符为冒号,与-F一样。

[root@openEuler-1 script]# head -n5 /etc/passwd | awk 'BEGIN{FS=":"}{print $1,$2}'
root x
bin x
daemon x
adm x
lp x

# 也可以使用-v来重新赋值这个变量,并指定输出分隔符
[root@openEuler-1 script]# head -n5 /etc/passwd | awk -vFS=':'  '{print $1,$2}'
root x
bin x
daemon x
adm x
lp x

# 也可以指定输出分隔符
[root@openEuler-1 script]# head -n5 /etc/passwd | awk 'BEGIN{FS=":";OFS="#"}{print $1,$2}'
root#x
bin#x
daemon#x
adm#x
lp#x

(2)RS和ORS

# 指定以某个字符作为分隔符来处理记录:
[root@openEuler-1 script]# echo "www.baidu.com/user/test.html" |awk 'BEGIN{RS="/"}{print $0}'
www.baidu.com
user
test.html

# 将输出的换行符替换为+号:
[root@openEuler-1 script]# seq 10 | awk 'BEGIN{ORS="+"}{print $0}'
1+2+3+4+5+6+7+8+9+10+[root@openEuler-1 script]#

(3)NF

# NF是字段个数
[root@openEuler-1 script]# echo "a b c d e f" | awk '{print NF}'
6

# 打印最后一个字段
[root@openEuler-1 script]# echo "a b c d e f" | awk '{print $NF}'
f

(4)NR和FNR

NR统计记录编号,每处理一行记录,编号就会+1,FNR不同的是在统计第二个文件时会重新计数。

[root@openEuler-1 script]# tail -n5 /etc/services | awk '{print NR,$0}'
1 axio-disc       35100/udp               # Axiomatic discovery protocol
2 pmwebapi        44323/tcp               # Performance Co-Pilot client HTTP API
3 cloudcheck-ping 45514/udp               # ASSIA CloudCheck WiFi Management keepalive
4 cloudcheck      45514/tcp               # ASSIA CloudCheck WiFi Management System
5 spremotetablet  46998/tcp               # Capture handwritten signatures

NR和FNR的区别:

[root@openEuler-1 script]# awk '{print NR,FNR,$0}' a b
1 1 a
2 2 b
3 3 c
4 1 d
5 2 e
6 3 f

(5)ARGC和ARGV

ARGC是命令行参数数量

ARGV是将命令行参数存到数组,元素由ARGC指定,数组下标从0开始

[root@openEuler-1 script]# awk 'BEGIN{print ARGC}' 1 2 3
4
[root@openEuler-1 script]# awk 'BEGIN{print ARGV[0],ARGV[1]}' 1 2 3
awk 1

(6)ARGIND

ARGIND是当前正在处理的文件索引值,第一个文件是1,第二个文件是2,以此类推,从而可以通过这种方式判断正在处理哪个文件。

[root@openEuler-1 script]# awk '{print ARGIND,$0}' a b
1 a
1 b
1 c
2 d
2 e
2 f

(7)ENVIRON

ENVIRON调用系统变量。

[root@openEuler-1 script]# awk 'BEGIN{print ENVIRON["HOME"]}'
/root

(8)FILENAME

FILENAME是当前处理文件的文件名。

[root@openEuler-1 script]# awk '{print FILENAME,$0}' a b
a a
a b
a c
b d
b e
b f

(9)IGNORECASE

IGNORECASE=1表示忽略大小写

[root@openEuler-1 script]# echo "A a b c" |xargs -n1 |awk 'BEGIN{IGNORECASE=1}/a/'
A
a

4.3 操作符

注意:在awk中,有3种情况表达式为假:数字是0,空字符串和未定义的值。且数值运算,未定义变量初始值为0。字符运算,未定义变量初始值为空。

(1)截取整数

[root@openEuler-1 script]# echo "123abc abc123 123abc123" |xargs -n1 | awk '{print +$0}'
123
0
123

[root@openEuler-1 script]# echo "123abc abc123 123abc123" |xargs -n1 | awk '{print -$0}'
-123
0
-123

(2)打印奇数偶数行

# 打印奇数行
[root@openEuler-1 script]# seq 6 | awk 'i=!i'
1
3
5

# 打印偶数行
[root@openEuler-1 script]# seq 6 | awk '!(i=!i)'
2
4
6

(3)管道符的使用

[root@openEuler-1 script]# seq 5 | shuf | awk '{print $0|"sort"}'
1
2
3
4
5
# 其中shuf会将原来的顺序打乱

(4)三目运算符

[root@openEuler-1 script]# awk 'BEGIN{print 1==1?"yes":"no"}'
yes

4.4 流程控制

(1)if语句

格式:if (condition) statement [ else statement ]

# 单分支
[root@openEuler-1 script]# seq 5 | awk '{if($0==3)print $0}'
3

# 双分支
[root@openEuler-1 script]# seq 5 |awk '{if($0==3)print $0;else print "no"}'
no
no
3
no
no

(2)while语句

格式:while (condition) statement

[root@openEuler-1 script]# echo "1 2 3 4 5" | awk '{i=1;while(i<=NF){print $i;i++}}'
1
2
3
4
5

(3)for语句C语言风格

格式:for (expr1; expr2; expr3) statement

[root@openEuler-1 script]# cat file
1 2 3
4 5 6
7 8 9
[root@openEuler-1 script]# awk '{for(i=1;i<=NF;i++)print $i}' file
1
2
3
4
5
6
7
8
9

(4)for语句遍历数组

格式:for (var in array) statement

[root@openEuler-1 script]# seq -f "str%.g" 5 |awk '{a[NR]=$0}END{for(v in a)print v,a[v]}'
1 str1
2 str2
3 str3
4 str4
5 str5

(5)break和continue语句

break跳过所有循环,continue跳过当前循环。

[root@openEuler-1 script]# awk 'BEGIN{for(i=1;i<=5;i++){if(i==3){break};print i}}'
1
2
[root@openEuler-1 script]# awk 'BEGIN{for(i=1;i<=5;i++){if(i==3){continue};print i}}'
1
2
4
5

(6)exit语句

格式:exit [ expression ]

exit退出程序,与shell的exit一样。[ expr ]是0-255之间的数字。

[root@openEuler-1 script]# seq 5 |awk '{if($0~/3/)exit (123)}'
[root@openEuler-1 script]# echo $?
123

4.5 内置函数

[root@openEuler-1 script]# cat c
123abc
abc123
123abc123
[root@openEuler-1 script]# awk '{print int($0)}' c
123
0
123

4.6  I/O语句

# 获取匹配行的下一行
[root@openEuler-1 script]# seq 5 |awk '/3/{getline;print}'
4

4.7 printf语句

格式化输出,默认打印字符串不换行。

格式:printf [format] arguments

# 左对齐宽度10
[root@openEuler-1 script]# awk 'BEGIN{printf "%-10s %-10s %-10s\n","ID","Name","Passwd"}'
ID         Name       Passwd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2278525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于 Spring Boot 和 Vue.js 的全栈购物平台开发实践

在现代 Web 开发中&#xff0c;前后端分离的架构已经成为主流。本文将分享如何使用 Spring Boot 和 Vue.js构建一个全栈购物平台&#xff0c;涵盖从后端 API 开发到前端页面实现的完整流程。 1. 技术栈介绍 后端技术栈 JDK 1.8&#xff1a;稳定且广泛使用的 Java 版本。 Spring…

Golang Gin系列-3:Gin Framework的项目结构

在Gin教程的第3篇&#xff0c;我们将讨论如何设置你的项目。这不仅仅是把文件扔得到处都是&#xff0c;而是要对所有东西的位置做出明智的选择。相信我&#xff0c;这些东西很重要。如果你做得对&#xff0c;你的项目会更容易处理。当你以后不再为了找东西或添加新功能而绞尽脑…

网络编程-UDP套接字

文章目录 UDP/TCP协议简介两种协议的联系与区别Socket是什么 UDP的SocketAPIDatagramSocketDatagramPacket 使用UDP模拟通信服务器端客户端测试 完整测试代码 UDP/TCP协议简介 两种协议的联系与区别 TCP和UDP其实是传输层的两个协议的内容, 差别非常大, 对于我们的Java来说, …

3.数据库系统

3.1数据库的基本概念 3.1.1:数据库体系结构 3.1.1.1集中式数据库系统 数据是集中的 数据管理是集中的 数据库系统的素有功能(从形式的用户接口到DBMS核心)都集中在DBMS所在的计算机 3.1.1.2C/S结构 客户端负责数据表示服务服务器主要负责数据库服务 数据库系统分为前端和后端…

探索 Transformer²:大语言模型自适应的新突破

目录 一、来源&#xff1a; 论文链接&#xff1a;https://arxiv.org/pdf/2501.06252 代码链接&#xff1a;SakanaAI/self-adaptive-llms 论文发布时间&#xff1a;2025年1月14日 二、论文概述&#xff1a; 图1 Transformer 概述 图2 训练及推理方法概述 图3 基于提示的…

【北京迅为】iTOP-4412全能版使用手册-第八十七章 安装Android Studio

iTOP-4412全能版采用四核Cortex-A9&#xff0c;主频为1.4GHz-1.6GHz&#xff0c;配备S5M8767 电源管理&#xff0c;集成USB HUB,选用高品质板对板连接器稳定可靠&#xff0c;大厂生产&#xff0c;做工精良。接口一应俱全&#xff0c;开发更简单,搭载全网通4G、支持WIFI、蓝牙、…

LDD3学习8--linux的设备模型(TODO)

在LDD3的十四章&#xff0c;是Linux设备模型&#xff0c;其中也有说到这个部分。 我的理解是自动在应用层也就是用户空间实现设备管理&#xff0c;处理内核的设备事件。 事件来自sysfs和/sbin/hotplug。在驱动中&#xff0c;只要是使用了新版的函数&#xff0c;相应的事件就会…

Jira中bug的流转流程

Jira中bug的状态 1. 处理Bug的流程2. bug状态流转详述bug的状态通常包括 1. 处理Bug的流程 2. bug状态流转详述 bug的状态通常包括 未解决 1. 测试人员创建一个bug&#xff0c;填写bug的详细信息&#xff0c;如概要、bug级别、复现步骤、现状、预期结果等 2. 定位bug&#x…

解决关于Xcode16提交审核报错

# 问题描述 The following issues occurred while distributing your application. Asset validation failed Invalid Executable. The executable xxx.app/Frameworks/HappyDNS.framework/HappyDNS contains bitcode.(lD:ef5dd249-731f-4731-8173-8e4a12519352) Asset valida…

windows下安装并使用node.js

一、下载Node.js 选择对应你系统的Node.js版本下载 Node.js官网下载地址 Node.js中文网下载地址??? 这里我选择的是Windows64位系统的Node.js20.18.0&#xff08;LTS长期支持版本&#xff09;版本的.msi安装包程序 官网下载&#xff1a; 中文网下载&#xff1a; 二、安…

基于SpringBoot+Vue旅游管理系统的设计和实现(源码+文档+部署讲解)

个人名片 &#x1f525; 源码获取 | 毕设定制| 商务合作&#xff1a;《个人名片》 ⛺️心若有所向往,何惧道阻且长 文章目录 个人名片环境需要技术栈功能介绍功能说明 环境需要 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 数据库&…

python之二维几何学习笔记

一、概要 资料来源《机械工程师Python编程&#xff1a;入门、实战与进阶》安琪儿索拉奥尔巴塞塔 2024年6月 点和向量&#xff1a;向量的缩放、范数、点乘、叉乘、旋转、平行、垂直、夹角直线和线段&#xff1a;线段中点、离线段最近的点、线段的交点、直线交点、线段的垂直平…

RabbitMQ---消息确认和持久化

&#xff08;一&#xff09;消息确认 1.概念 生产者发送消息后&#xff0c;到达消费端会有以下情况&#xff1a; 1.消息处理成功 2.消息处理异常 如果RabbitMQ把消息发送给消费者后就把消息删除&#xff0c;那么就可能会导致&#xff0c;消息处理异常想要再获取这条消息的时…

map和set c++

关联式容器也是⽤来存储数据的&#xff0c;与序列式容器不同的是&#xff0c;关联式容器逻辑结构通常是⾮线性结构&#xff0c;两个位置有紧密的关联关系&#xff0c;交换⼀下&#xff0c;他的存储结构就被破坏了。顺序容器中的元素是按关键字来保存和访问的。关联式容器有map/…

turtle教学课程课堂学习考试在线网站

完整源码项目包获取→点击文章末尾名片&#xff01;

Digital Document System (DDS)

Digital Document System (DDS&#xff09; 数字档案平台 信息注入

Springer Nature——Applied Intelligence 投稿指南

投稿系统&#xff1a;Editorial Manager (Manuscript and Peer Review) : 使用Editorial Manager 投稿系统的期刊列表&#xff1a;期刊列表 期刊主页&#xff1a;Spring Nature 主页 投稿主页&#xff1a;Spring Nature Submit SystemSubmission Guidelines: Official Submissi…

如何在前端给视频进行去除绿幕并替换背景?-----Vue3!!

最近在做这个这项目奇店桶装水小程序V1.3.9安装包骑手端V2.0.1小程序前端 最近&#xff0c;我在进行前端开发时&#xff0c;遇到了一个难题“如何给前端的视频进行去除绿幕并替换背景”。这是一个“数字人项目”所需&#xff0c;我一直在冥思苦想。终于有了一个解决方法…

使用python+pytest+requests完成自动化接口测试(包括html报告的生成和日志记录以及层级的封装(包括调用Json文件))

一、API的选择 我们进行接口测试需要API文档和系统&#xff0c;我们选择JSONPlaceholder免费API&#xff0c;因为它是一个非常适合进行接口测试、API 测试和学习的工具。它免费、易于使用、无需认证&#xff0c;能够快速帮助开发者模拟常见的接口操作&#xff08;增、删、改、…

UE4原生的增量Cook原理

设置Cook的步骤后&#xff0c;断点进入到如下堆栈&#xff1a; UCookOnTheFlyServer::StartCookByTheBook(const UCookOnTheFlyServer::FCookByTheBookStartupOptions &) CookOnTheFlyServer.cpp:7723 UCookCommandlet::CookByTheBook(const TArray<…> &, TArr…