续正则表达式与Linux文本三剑客Day1
sed命令 sed的工作流 语法 1 sed [option] [sed内置命令字符] [file]
选项 1 2 3 4 5 6 7 -n 取消默认sed的输出,常与sed内置命令p一起使用 -i 直接修改结果写入文件,不用-i,sed修改的是内存数据 -e 多次编辑,不需要管道符了 -r 支持拓展正则,sed默认支持基本正则
sed内置命令字符 sed的内置命令字符用于对文件进行不同的操作功能,如对文件增删改查
sed的内置命令字符
解释
a
append,对文本追加,在指定行后面添加一行/多行文本
d
Delete,删除匹配行
i
insert,插入文本,在指定行前添加一行/多行文本
p
print,打印匹配行的内容,通常与-n参数一起使用
s/正则/替换内容/g或者s#正则#替换内容#g或者s@正则@替换内容@g
匹配正则内容,然后替换内容(支持正则),结尾g代表全局匹配
匹配范围
范围
解释
空地址
全文处理,如:使用a时不指定行,则会在每一行后添加内容
单地址
指定文件某一行,如:1a,在第一行后添加内容
/pattern/
被模式匹配到的每一行
范围区间
10,20 十到二十行 ;10,+5第10行向下5行 ;/pattern1/,/pattern2/匹配多个模式
步长
1~2表示1,3,5,7,9…奇数行;2~2两个步长表示2,4,6,8…偶数行
内置命令实践
准备数据文件sed.txt
配合正则表达实践
awk命令
awk是一个强大的Linux命令,有强大的文本格式化能力,好比将一些文本数据格式化成excel表的样式。
也是一行一行处理
awk默认以空格
为分隔符,且多个空格识别为一个空格作为分隔符
awk是按行处理文件,一行处理完毕,处理下一行,根据用户指定的分隔符去工作,没有指定则默认空格
指定了分隔符后,awk把每一行切割后的数据对应到内置变量
awk早期在Unix上实现,awk是gawk,GUN awk的意思;
awk更是一门编程语言,支持条件判断、数组、循环等功能。
语法 1 2 awk [option] 'pattern{action}' file ...
最常用的action是:print/printf,即打印
选项 1 2 3 -F 指定分割字段符 -v 定义或修改一个awk内部的变量 -f 从脚本文件中读取awk命令
awk内置变量
awk ‘{print $2}’,没有使用参数和模式时,$2
表示输出文本的第二列
信息。
1 2 3 4 5 6 7 8 9 10 $0 代表一整行$1 $2 $3 ... 代表第一列第二列第三列...(第一个字段、第二个、第三个.....)$NF 代表最后一列(最后一个字段)$(NF-1) 代表倒数第二列(倒数第二个字段) FS 字段分隔符,默认是空格 NF(Number of fields) 分割后,当前行一共有多少个字段 NR(Number of records) 当前记录数、行数 man awk
想要输入第一列第二列第三列时,$1$2$3用逗号
隔开,输出的结果就不会挨在一起而是有默认空格分隔。
awk自定义输出内容在单引号中使用双引号括起来,如:
1 awk '{print "第一列:"$1,"第二列:"$2}'
实践 准备文件awk1.txt 1 2 3 4 a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4
显示文件第五行
NR==5
=
在Linux表示修改变量值,==
表示关系运算符
1 awk 'NR==5{print $0}' awk1.txt
执行演示
显示文件第二行到第六行 1 awk 'NR==2,NR==6{print $0}' awk1.txt
执行演示
为文件每一行添加行号 1 awk '{print NR,$0}' awk1.txt
执行演示
显示文件第一列、倒数第三列、最后一列
NF
1 awk '{print $1,$(NF-2),$NF'
执行演示
使用awk取出ip地址
利用awk以空格为分隔符的特性
ipconfig eth0
1 ipconfig eth0|awk 'NR==2{print $2}'
执行演示
替换空格为其他分隔符 准备文件awk2.txt
awk的分隔符有两种
输入分隔符,awk默认是空格、空白字符,英文是field separator,变量名为FS
输出分隔符,output field separator,简称OFS
FS输入分隔符
使用参数可以指定分隔符
实例
输出第一列和最后一列
1 awk -F ":" '{print $1,$NF}' awk2.txt
通过修改awk内置变量
分隔符来实现指定分隔符
执行演示
1 2 3 4 5 6 7 8 [root@localhost ~] a:b:c:d 1:2:3:4 x:x:x:x [root@localhost ~] a d 1 4 x x
实例
输出第二列和倒数第二列
1 awk -v FS=":" '{print $2,$(NF-1)}' awk2.txt
执行演示
1 2 3 4 5 6 7 8 [root@localhost ~] a:b:c:d 1:2:3:4 x:x:x:x [root@localhost ~] b c 2 3 x x
OFS输出分隔符
当我们在输出使用逗号
时,默认使用空格分割
awk -F “:” ‘{print $1,$2,$3,$4}’ awk2.txt
如果需要修改逗号
的默认输出分隔符,我们可以修改OFS变量
1 awk -F ":" -v OFS="---" '{print $1,$2,$3,$4}' awk2.txt
执行演示
1 2 3 4 5 6 7 8 9 10 11 12 [root@localhost ~] a b c d 1 2 3 4 x x x x [root@localhost ~] a:b:c:d 1:2:3:4 x:x:x:x [root@localhost ~] a---b---c---d 1---2---3---4 x---x---x---x
awk内置命令补充
awk变量分为
1 2 3 4 5 6 RS 输入记录分隔符(输入换行符),指定输入时的换行符 ORS 输出记录分隔符(输出换行符),指定输出时的换行符 FNR 各文件分别技术的行号 FILENAME 当前文件名 ARGC 命令行参数的个数 ARGV 数组,保存的是命令行所给定的各参数
实践 处理多个文件显示行号
当作整体的情况
1 awk '{print NR,$0}' awk1.txt awk2.txt
执行演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4 [root@localhost ~] a:b:c:d 1:2:3:4 x:x:x:x [root@localhost ~] 1 a1 a2 a3 a4 2 b1 b2 b3 b4 3 c1 c2 c3 c4 4 d1 d2 d3 d4 5 a:b:c:d 6 1:2:3:4 7 x:x:x:x
RS 更换输入换行分隔符 1 awk -v RS=" " {print $0 } awk1.txt
执行演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4 [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4
ORS 更换输出换行分隔符 1 awk -v ORS=" " '{print $0}' awk1.txt
执行演示
1 2 3 4 5 6 7 8 9 [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4 [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4 [root@localhost ~] [root@localhost ~] a1 a2 a3 a4换行符b1 b2 b3 b4换行符c1 c2 c3 c4换行符d1 d2 d3 d4换行符[root@localhost ~]
数组ARGV变量的使用
BEGIN 模式,表示做什么事前先做什么事
1 awk 'BEGIN{print "这句话先做!"} {print $0}' awk1.txt
ARGV
1 2 3 4 awk 'BEGIN{print "这句话先做!"} {print ARGV[0],$0}' awk1.txt awk 'BEGIN{print "这句话先做!"} {print ARGV[1],$0}' awk1.txt awk 'BEGIN{print "这句话先做!"} {print ARGV[2],$0}' awk1.txt awk 'BEGIN{print "这句话先做!"} {print ARGV[3],$0}' awk1.txt
执行演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [root@localhost ~] 这句话先做 a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4 [root@localhost ~] awk a1 a2 a3 a4 awk b1 b2 b3 b4 awk c1 c2 c3 c4 awk d1 d2 d3 d4 [root@localhost ~] awk1.txt a1 a2 a3 a4 awk1.txt b1 b2 b3 b4 awk1.txt c1 c2 c3 c4 awk1.txt d1 d2 d3 d4 [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4 [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4
从上面的结果我们可以看出数组ARGV[0],ARGV[1]分别存储的是命令awk,文件名awk1.txt
再通过一条命令就可以理解ARGV[]数组了
1 awk '{print ARGV[0],ARGV[1],ARGV[2]}' awk1.txt awk2.txt
执行演示
1 2 3 4 5 6 7 8 [root@localhost ~] awk awk1.txt awk2.txt awk awk1.txt awk2.txt awk awk1.txt awk2.txt awk awk1.txt awk2.txt awk awk1.txt awk2.txt awk awk1.txt awk2.txt awk awk1.txt awk2.txt
awk自定义变量 方法一 在awk中使用-v定义 1 awk -v var="这是一个变量" '{print var,$1}' awk2.txt
方法二 在程序中直接定义(两种写法) 1 2 3 4 5 6 7 8 9 10 [root@localhost ~]# awk '{var1="变量1";var2="变量2";print var1,var2,$0}' awk1.txt 变量1 变量2 a1 a2 a3 a4 变量1 变量2 b1 b2 b3 b4 变量1 变量2 c1 c2 c3 c4 变量1 变量2 d1 d2 d3 d4 [root@localhost ~]# awk '{var1="变量1";var2="变量2"}{print var1,var2,$0}' awk1.txt 变量1 变量2 a1 a2 a3 a4 变量1 变量2 b1 b2 b3 b4 变量1 变量2 c1 c2 c3 c4 变量1 变量2 d1 d2 d3 d4
方法三 间接引用shell变量(必须加BEGIN
动作) 1 2 var=变量 awk -v var=$var 'BEGIN{print var}'
格式化
print只能简单的输出文本,并不能美化或者
或者修改格式
prinf格式化输出
printf与print的区别
printf需要指定format
format用于指定后面的每个item的输出格式
printf语句不会自动打印换行符
1 2 3 4 5 awk '{print $0}' awk1.txt awk '{printf $0}' awk1.txt awk '{print $0}' awk1.txt awk '{printf "%s\n",$0}' awk1.txt
执行演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4 [root@localhost ~] a1 a2 a3 a4b1 b2 b3 b4c1 c2 c3 c4d1 d2 d3 d4[root@localhost ~] [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4 [root@localhost ~] a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 d1 d2 d3 d4
使用%s\n可以实现print的换行
format格式的指示符都以%开头,后面跟一个字符
1 2 3 4 5 6 7 8 9 10 11 12 %c 显示字符的ASCII码 %d,%i 匹配十进制整数 %e,%E 科学计数显示数值 %f 显示浮点数 %g,%G 以科学计数法的格式或浮点数的格式显示数值 %s 匹配字符串 %v 无字符整数 %% 显示%本身 printf 修饰符- 左对齐,默认是右对齐 + 显示数值符号,printf "%+d"
针对多个变量进行格式化
Linux中使用printf命令格式化字符
1 2 3 4 [root@localhost ~] 1 2 3
awk中使用printf格式化字符
1 2 awk 'BEGIN{printf "%d\n",1,2,3}' awk 'BEGIN{printf "%d\n%d\n%d\n",1,2,3}'
1 2 3 4 5 6 [root@localhost ~] 1 [root@localhost ~] 1 2 3