1.常用元字符
^ 行首定位符 ^love
$ 行尾定位符 love$
. 任意单个字符 l..e
* 前导符0到n次 ab*love
.* 任意多个字符
[] 匹配指定范围内一个字符 [lL]
[-] 匹配指定范围内一个字符 [a-z0-9]ove
[^] 匹配不在组内的字符 [^a-z0-9]ove
\ 转义字符 love\.
\< 词首定位符 \<love
\> 词尾定位符 love\>
\(..\) 匹配稍后使用的字符标签 :%s/192.168.211.1/192.168.211.5/
:%s/\(192.168.211.\)1/\15/
:%s/\(192.\)\(168.\)\(211.\)1/\1\2\33/
:%3,9s/\(.*)/#\1/
x\{m\} 字符x重复出现m次 o\{5\}
x\{m,\} 字符x重复出现m次以上 o\{5,\}
x\{m,n\} 字符x重复出现m-n次 o\{5,10\}
拓展
+ 匹配一个或多个前导字符 [a-z]+love
? 匹配零个或多个前导字符 lo?ve
a|b 匹配a或b love|hate
() 组字符
(..)(..)\1\2 标签匹配字符 (love)able\1er
x{m} 字符x重复m次 a{2}
x{m,} 字符x重复至少m次 b{3,}
x{m,n} 字符x重复m到n次 c{1,5}
2.shell编程-grep家族
grep: 在文件中全局查找指定的正则表达式,并打印该表达式所有的行
egrep: grep的拓展,支持更多的正则表达式元字符
fgrep: 固定grep,按字面解释所有的字符
grep [选项] PATTERN filename filename ...
#grep 'hello world' /tmp/test
找到 grep返回的退出状态为0
找不到 grep返回的退出状态为0
找不到指定文件 grep返回的退出状态为0
grep使用的元字符
grep: 使用的基本元字符集 ^,$,.,*,[],[^],\<\>,\(\),\{\}
egrep(grep -E):使用的基本元字符集 ?,+,{},|,()
\w 所有字母与数字,称为字符 [a-zA-Z0-9] 'l[a-zA-Z0-9]'*ve 'l\w*ve'
\W 所有字母与数字之外的字符即非字符 'love[^a-zA-Z0-9]+' 'love\W+'
\b 词边界 '\<love\>' '\blove\b'
grep选项
-i --ignore-case 忽略大小写
-l --files-with-matches 只列出匹配行所在文件名
-n --line-number 在每一行前面加上它的文件中的相对好
-c --count 显示成功匹配的行数
-s --no-messages 禁止显示文件不存在或文件不可读的错误信息
-q --quiet,--silent 静默
-V --invert-match 反向查找,只显示不匹配的行
-R,-r --recursive 递归针对目录
-color 颜色
-O --only-matching 只显示匹配内容
-B --before-context=NUM print NUM lines of leading context
-A --after-context=NUM print NUM lines of trailing context
-C --context=NUM print NUM lines of output context
3.shell编程流编辑器sed
非交互式编辑器,一次处理一行内容
sed主要用来自动编辑一个或多个 文件,简化对文件的反复操作,编写转换程序等
sed -ri.bak (i比较危险,一般加上.bak)
sed -ric --follow-symlinks
命名格式
sed [options] 'command' file(s) 主要用这个
sed [options] -f scriptfile file(s)
sed和grep不同,无论是否找到指定的模式,它的退出状态都是0,只有当语法存在错误时候,sed的退出状态才是非0
sed "参数" '模式'
参数 1 -f 指定一个规则文件 2 -n 阻止输入行输出 -r 扩展正则
模式 1 s 替换 2 g 整行 3 d 删除 4 p 打印
支持正则表达式
使用基本元字符集 ^,$,.,*,[],[^],\<\>,\(\),\{\}
使用拓展元字符集 ?,+,{},|,()
使用拓展元字符方式:
\+
sed -r
sed命令
sed命令告诉sed对指定进行何种操作,包括打印、删除、修改等。
命令 功能
a 在当前行后添加一行或多行
c 用新文本修改(替换)当前行中的文本
d 删除行
l 列出非打印字符
i 在当前行之前插入文本
p 打印行
n 读入下一行,并从下一行命令而不是第一条命令开始对其处理
q 结束或退出sed
! 对所选行以外的所有行应用命令
写文件命令:w
#sed -r '/north/w newfile' datafile
#sed -r '3,$w /new1.txt' datafile
追加命令:a
#sed -r '2a\1111111111' /etc/hosts
#sed -r '2a\11111111111\
>22222222222\
>333333333333' /etc/hosts
插入命令:i
#sed -r '2i\11111111111' /etc/hosts
#sed -r '2i111111111\
2222222\
333333333' /etc/hosts
修改命令:c
#sed -r '2c\111111111' /etc/hosts
#sed -r '2c\11111111\
>2222222222\
3333333333' /etc/hosts
获取下一行命令:n
#sed -r '/eastern/{ n;d }' datafile
#sed -r '/eastern/{ n;s/AM/Archile }' datafile
暂存和取用命令:h H g G
#sed -r '1h;$G' /etc/hosts
#sed -r '1{h;d};$G' /etc/hosts
#sed -r '1h;2,$g' /etc/hosts
#sed -r '1h;2,3H;$G' /etc/hosts
暂存空间和模式空间互换命令:x
#sed -r '4h;5x;6G' /etc/hosts
反向选择:!
#sed -r '3d' /etc/hosts
#sed -r '3!d' /etc/hosts
多重编辑选项:e
#sed -r -e '1,3d' -e 's/Hememway/Jones' datafile
#sed -r '1,3d; s/Hememway/Jones' datafile
#sed -r '2s/WE/1000phone/g; 2s/Gray/YYY/g' datafile
#sed -r '2s{s/WE/1000phone/g; s/Gray/YYY/g}' datafile
sed常见操作
删除配置文件中#号注释行
sed -ri '/^[ \t]*#/d' file.conf
删除配置文件中//号注释行
sed -ri '\Y^[ \t]*//Yd' file.conf
删除无内容空行
sed -ri '/^[ \t]*$/d' file.conf
4.shell编程-awk
awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息
awk处理过程: 依次对每一行进行处理,然后输出 默认分隔符是空格或者tab键
BEGIN{} {}
行处理前
END{}
行处理 行处理后
[root@newrain ~]# awk 'BEGIN{print 1/2} {print "ok"} END{print "----"}' /etc/hosts
0.5
ok
ok
ok
ok
ok
ok
----
awk工作原理
awk -F":" '{print $1,$3}' /etc/passwd
(1)awk使用一行作为输入,并将这一行赋给变量$0,每一行可称作为一个记录,以换行符结束
(2)然后,行被:分解成字段,每个字段存储在已编号的变量中,从$1开始
(3)awk如何知道空格来分隔字段的呢?因为有一个内部变量FS来确定字段分隔符,初始时,FS赋为空格或者是tab
(4)awk打印字段时,将以设置的方法,使用print函数打印,awk在打印的字段间加上空格,因为$1,$3间有一个,逗号。逗 号比较特殊,映射为另一个变量,成为输出字段分隔符OFS,OFS默认为空格
(5)awk打印字段时,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处 理。该过程持续到处理文件结束。
默认分隔符是空格或者tab键
awk中的特殊变量:
常用:
- NR: 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号
- NF: 表示字段数量, 当awk将行为记录时, 该变量相当于当前列号
难理解:
FS(输入字段分隔符)
OFS(输出字段分隔符)
NR(Number of record)行数
FNR按不同的文件分开
RS(输入记录分隔符)
ORS(输出记录分隔符)
NF 字段个数
S
FS(输入字段分隔符) (filed sign)
[root@newrain ~]# awk 'BEGIN{FS=":"} {print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
OFS(输出字段分隔符) (output filed sign)
[root@newrain ~]# awk 'BEGIN{FS=":";OFS=".."} {print $1,$2}' /etc/passwd
root..x
bin..x
daemon..x
adm..x
lp..x
sync..x
shutdown..x
NR 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号
[root@newrain ~]# awk -F: '{print NR,$0}' a.txt file1.txt
1 love
2 love.
3 loove
4 looooove
5
6 isuo
7 IPADDR=192.168.6.5
8 hjahj123
9 GATEWAY=192.168.1.1
10 NETMASK=255.255.255.0
11 DNS=114.114.114.114
FNR 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号(不同文件分开)
[root@newrain ~]# awk -F: '{print FNR,$0}' a.txt file1.txt
1 love
2 love.
3 loove
4 looooove
5
1 isuo
2 IPADDR=192.168.6.5
3 hjahj123
4 GATEWAY=192.168.1.1
5 NETMASK=255.255.255.0
6 DNS=114.114.114.114
RS(输入记录分隔符)
[root@newrain ~]# cat 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@newrain ~]# awk -F: 'BEGIN{RS="bash"} {print $0}' passwd
root:x:0:0:root:/root:/bin/
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
ORS(输出记录分隔符)
[root@newrain ~]# cat 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@newrain ~]# awk -F: 'BEGIN{ORS=" "} {print $0}' 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
格式化输出
print函数
#date |awk '{print "Month:"$2"\nYear:"$NF}'
#awk -F":" '{print "username is: "$1"\1 uid is:"$3 }' /etc/passwd
#awk -F":" '{print "\tusername and uid:" $1,$3"!"} /etc/passwd
printf函数
#awk -F":" '{printf "%-15s %-10s %-15s\n",$1,$2,$3}' /etc/passwd
#awk -F":" '{printf "|%-15s |%-10s |%-15s\n",$1,$2,$3}' /etc/passwd
%s 字符类型
%d 数值类型
占15字符
- 表示左对齐,默认是右对齐
printf默认不会在行尾自动换行,加\n
任何awk语句都是由模式和动作组成,模式部分决定动作语句何时触发事件。处理就是对数据进行操作。如果省略模式部分,动作将时刻保持执行状态。模式可以是任何条件语句或复合语句或正则语句。模式包括两个特殊字段BEGIN和END。
==正则表达式
匹配记录(整行):
#awk '/^alice/' /etc/passwd
#awk '$0 ~ /^alice/' /etc/passwd
#awk '!/alice/' passwd
#awk '$0 !~ /^alice/' /etc/passwd
匹配字段:匹配操作符(~ !~)
#awk -F":" '$1 ~ /^alice/' /etc/passwd
#awk -F":" '$NF !~ /bash$/' /etc/passwd
==比较表达式
比较表达式采用对文本进行比较,只有条件为真时,才执行指定动作。比较表达式使用关系运算符,用于比较数字和字符串。
关系运算符
运算符 含义
< 小于
<= 小于等于
== 等于
!= 不等于
>= 大于等于
> 大于
#awk -F ":" '$3 == 0' /etc/passwd
#awk -F ":" '$3 < 10' /etc/passwd
#awk -F ":" '$7 == "/bin/bash"' /etc/passwd
#awk -F ":" '$1 =="root"' /etc/passwd
#awk -F ":" '$1 ~ /roo/' /etc/passwd
#awk -F ":" '$1 !~ /root/' /etc/passwd
#df -P |grep "/" |awk '$4 > 25000'
==条件表达式:
#awk -F":" '$3>300 {print $0}' /etc/passewd
#awk -F":" '{ if($3>300) print $0 }' /etc/passewd
#awk -F":" '{ if($3>300) {print $0} }' /etc/passewd
#awk -F":" '{ if($3>300) {print $3} else{print $1} }' /etc/passewd
==算数表达式
#awk -F":" '$3 * 10 > 500' /etc/passewd
#awk -F":" '{ if($3*10>500) {print $0} }' /etc/passewd
==逻辑操作符和复合模式
&& 逻辑与 a&&b
|| 逻辑或 a||b
! 逻辑非 !a
#awk -F":" '$1~/root/ && $3<=15' /etc/passwd
#awk -F":" '$1~/root/ || $3<=15' /etc/passwd
#awk -F":" '!($1~/root/ || $3<=15)' /etc/passwd
==范围模式
#awk '/Tom/,/Suzanne' filename
==条件判断
if语句:
{if(表达式){语句;语句;...}}
if...else语句:
{if(表达式){语句;语句;...} else(表达式){语句;语句;...}}
if..else if..else语句:
{if(表达式){语句;语句;...} else if(表达式){语句;语句;...} else if(表达式){语句;语句;...} else{语句;语句;...}}
逻辑或 a||b
! 逻辑非 !a
#awk -F":" '$1~/root/ && $3<=15' /etc/passwd
#awk -F":" '$1~/root/ || $3<=15' /etc/passwd
#awk -F":" '!($1~/root/ || $3<=15)' /etc/passwd
==范围模式
#awk '/Tom/,/Suzanne' filename
==条件判断
if语句:
{if(表达式){语句;语句;...}}
if...else语句:
{if(表达式){语句;语句;...} else(表达式){语句;语句;...}}
if..else if..else语句:
{if(表达式){语句;语句;...} else if(表达式){语句;语句;...} else if(表达式){语句;语句;...} else{语句;语句;...}}