1.Shell脚本之grep篇
egrep 支持正则表达式的拓展元字符 (或grep -E)
1.1运用正则,判断需要[[ ]]
[root@newrain ~]# [[ $num1 =~ ^[0-9]+$ ]] && echo "yes" || echo "no"
yes
[root@newrain ~]# num3=1b1
[root@newrain ~]# [[ $num3 =~ ^[0-9]+$ ]] && echo "yes" || echo "no"
no
[root@newrain ~]# [[ $num =~ ^[0-9]+\.[0-9]+$ || $num =~ ^[0-9]+$ ]] && echo "yes" || echo "no" //输入的只能是数字(包括小数)
1.2 2、* 0或多个
[root@newrain ~]# useradd abrt
[root@newrain ~]# grep 'abc*' /etc/passwd
abrt:x:1041:1041::/home/abrt:/bin/bash
1.3 \< 词首定位符号 \>词尾定位符号
[root@newrain ~]# cat jack.txt
Jack JACK JAck jackly
:% s/\<[Jj]ack\>/123/g
1.4 ^以什么开头
[root@newrain ~]# grep '^root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
1.5 $以什么结尾
[root@newrain ~]# grep 'bash$' /etc/passwd
root:x:0:0:root:/root:/bin/bash
confluence:x:1000:1000:Atlassian Confluence:/home/confluence:/bin/bash
to:x:1003:1003::/home/to:/bin/bash
1.6 . 匹配单个字符
[root@newrain ~]# grep 'r..t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin
[root@newrain ~]# grep 'r.t' /etc/passwd
operator:x:11:0:operator:/root:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
1.7 .* 任意多个字符
[root@newrain ~]# grep 'r.*t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin polkitd:x:999:997:User for polkitd:/:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
abrt:x:1041:1041::/home/abrt:/bin/
1.8 [] 匹配方括号中的任意一个字符
[root@newrain ~]# grep 'Root' /etc/passwd
[root@newrain ~]# grep '[Rr]oot' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin
1.9 [ - ] 匹配指定范围内的一个字符
[root@newrain ~]# grep [a-z]oot /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin
1.10 [^] 匹配不在指定组内的字符,取反得意思
[root@newrain ~]# grep '[^0-9]oot' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
dockerroot:x:998:995:Docker User:/var/lib/docker:/sbin/nologin
扩展正则表达式元字符
+ 匹配一个或多个前导字符
[a-z]+ove
? 匹配零个或一个前导字符
lo?ve
a|b 匹配a或b
love|hate
(..)(..)\1\2 标签匹配字符
(love)able\1er
x{m} 字符x重复m次
o{5
x{m,} 字符x重复至少m次
o{5,}
x{m,n} 字符x重复m到n次
o{5,10}
2.Shell脚本之Sed篇
非交互式编辑器,一次处理一行内容。(流文本编辑器)
sed "参数" '模式'
参数 1 -f 指定一个规则文件 2 -n 阻止输入行输出 -r 扩展正则
模式 1 s 替换 2 g 整行(也可以是数字,替换第几个) 3 d 删除 4 p 打印 5 a 追加 6 i 是插入
sed: stream editor(流编辑器)的缩写. 它们最常见的用法是进行文本的替换。
[root@newrain ~]# sed '1d' passwd //删除文件的第1行
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# sed '1,2d' passwd //删除文件的第1到2行 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# cat e.txt
/etc/abc/456
etc
[root@newrain ~]# sed -r 's#/etc/abc#/var/lib#' e.txt
/var/lib/456
etc
[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 ~]# sed '2,$d' passwd //删除第2行到最后一行
root:x:0:0:root:/root:/bin/bash
[root@newrain ~]# sed '/root/d' passwd //匹配到root,删除此行
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# sed '/root/,2d' passwd //匹配到root行,到某一行
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@newrain ~]# sed '1~2d' passwd //删除奇数行
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
operator:x:11:0:operator:/root:/sbin/nologin
[root@newrain ~]# sed '0~2d' passwd //删除偶数行
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
2.1 sed可以从stdin中读取内容
`$ cat filename | sed 's/pattern/replace_string/' `
2.2 选项 -i 会使得sed用修改后的数据替换原文件
`$ sed -i 's/pattern/replace_string/' filename `
2.3 g标记可以使sed执行全局替换
$ sed 's/pattern/replace_string/g' filename
$ sed 's/pattern/replace_string/gi' filename //忽略大小写替换
2.4 g标记可以使sed匹配第N次以后的字符被替换
` $ echo "thisthisthisthis" | sed 's/this/THIS/2g' `
2.5 sed中的分隔符可以替换成别的字符, 因为s标识会认为后面的字符为分隔符
$ sed 's:text:replace_text:'
$ sed 's|text|replace_text|'
2.6 sed可以利用指令来删除文件中的空行
`$ sed '/^$/d' filename `
2.7 由于在使用 -i 参数时比较危险, 所以我们在使用i参数时在后面加上.bak就会产生一个备份的文件,以防后悔
`sed -i.bak 's/pattern/replace_string/' filename `
2.8 在文件中匹配到的部分前后加上一行
sed '/^bin/a\hello nihao/' passwd # 在匹配到开头为bin的行下一行插入内容
sed '/^bin/i\hello nihao/' passwd # 在匹配到开头为bin的行上一行插入内容
3.Shell脚本之AWK篇
awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息。
awk处理过程: 依次对每一行进行处理,然后输出 默认分隔符是空格或者tab键。
awk 参数 'BEGIN{处理之前要做的} {处理内容} END{处理之后的内容}'
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中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程持续到处理文件结束。
awk中的特殊变量:
常用:
- NR: 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号
- NF: 表示字段数量, 当awk将行为记录时, 该变量相当于当前列号
FS(输入字段分隔符) # 以什么符号去分割
OFS(输出字段分隔符) # 以什么分隔符显示
NR(Number of record)行数
FNR按不同的文件分开
RS(输入记录分隔符)
ORS(输出记录分隔符)
NF 字段个数
3.1 NR 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号
[root@newrain ~]# awk -F: '{print NR,$0}' a.txt file1.txt
1 love
2 love.
3 loove
4 looooove
3.2 FNR 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号(不同文件分开)
[root@newrain ~]# awk -F: '{print FNR,$0}' a.txt file1.txt
1 love
2 love.
3 loove
4 looooove
3.3 AWK使用理解案例
1. 打印一个文件中的第2列和第3列
$ awk '{ print $2, $3}' filename
2. 打印指定行指定列的某个字符
$ awk -F":" 'NR==3{ print $7 }' /etc/passwd
3. 统计一个文件的行数
$ awk '{ print NR}' filename
4. 在脚本中, 传递变量到awk中
$ var=1000
$ echo | awk -v VARIABLE=$var '{ print VARIABLE }'
5. 指定字段分隔符-F或在BEGIN{ FS=":" }
$ awk -F: '{ print $2, $3 }' filename
$ awk 'BEGIN{ FS=":" }{ print $2, $3 }' filename
6. 在awk中使用for循环
每行打印两次
[root@newrain ~]# awk -F: '{for(i=1;i<=2;i++) {print $0}}' passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
分别打印每行每列
[root@newrain ~]# awk -F: '{ for(i=1;i<=NF;i++) {print $i}}' passwd
7. 在awk中使用if条件判断
显示管理员用户名
[root@newrain ~]# awk -F: '{if($3==0) {print $1 " is administrator."}}' /etc/passwd
统计系统用户
[root@newrain ~]# awk -F":" '{if($3>0 && $3<1000){i++}} END{print i}' /etc/passwd