目录
一.awk
1.基础概述
格式:
awk [options] 'program' var=value file…
说明: program通常是被放在单引号中,并可以由三种部分组成
• BEGIN语句块
• 模式匹配的通用语句块
• END语句块
常见选项:
• -F “分隔符” 指明输入时用到的字段分隔符,默认的分隔符是若干个连续空白符
• -v var=value 变量赋值
Program格式:
pattern{action statements;..}
• pattern:决定动作语句何时触发及触发事件,比如:BEGIN,END,正则表达式等
• action statements:对数据进行处理,放在{}内指明,常见:print, printf
- output statements:print,printf
- Expressions:算术,比较表达式等
- Compound statements:组合语句
- Control statements:if, while等
- input statements
2.awk 常见的内置变量
awk 选项 '模式{print }'
• FS :指定每行文本的字段分隔符,缺省默认为空格或制表符(tab)。与 “-F”作用相同 -v "FS=:"
• OFS:输出时的分隔符
• NF:当前处理的行的字段个数
• NR:当前处理的行的行号(序数)
• $0:当前处理的行的整行内容
• $n:当前处理行的第n个字段(第n列)
• FILENAME:被处理的文件名
• RS:行分隔符。awk从文件上读取资料时,将根据RS的定义就把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是\n
3.自定义变量
printf
%s:显示字符串
%d, %i:显示十进制整数
%f:显示为浮点数
%e, %E:显示科学计数法数值
%c:显示字符的ASCII码
%g, %G:以科学计数法或浮点形式显示数值
%u:无符号整数
%%:显示%自身
4.模式PATTERN
awk '模式{处理动作}'
PATTERN:根据pattern条件,过滤匹配的行,再做处理
4.1模式为空
如果模式为空表示每一行都匹配成功,相当于没有额外条件
awk -F: '{print $1,$3}' /etc/passwd
4.2正则匹配
/regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
例子: awk '/^UUID/{print $1}' /etc/fstab
4.3 line ranges:行范围
不支持使用行号,但是可以使用变量NR 间接指定行号加上比较操作符 或者逻辑关系
算术操作符
x+y, x-y, x*y, x/y, x^y, x%y
-x:转换为负数
+x:将字符串转换为数值
比较操作符:
==, !=, >, >=, <, <=
逻辑符号:
与:&&,并且关系
或:||,或者关系
非:!,取反
模式匹配符:
~ 左边是否和右边匹配,包含关系
!~ 是否不匹配
4.5 关系表达式(扩展)
关系表达式结果为“真”才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串或0值
seq 10 |awk 'n++' 打印除了第一行
seq 10 |awk '!n++' 只打第一行
seq 10 |awk 'i=!i' 奇数行
seq 10 |awk -v i=1 'i=!i' 偶数行
seq 10 |awk '!(i=!i)' 偶数行
5. 条件判断(扩展)
awk 选项 '模式 {actions}'
条件判断写在 actions里
if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2}else if(condition3){statement3}...... else {statementN}
condition1:条件
statement1:语句 i
f语句:awk的if语句也分为单分支、双分支和多分支
单分支为if(判断条件){执行语句}
双分支为if(判断条件){执行语句}else{执行语句}
多分支为if(判断条件){执行语句}else if(判断条件){执行语句}else if(判断条件){执行语句}else if(判断条件){执行语句}
#写在动作里[root@localhost ~]#awk -F: '{if($3>1000)print $1,$3}' /etc/passwd
nfsnobody 65534mysql 1001lisi 1002liwu 1003
[root@localhost ~]#awk -F: '{if($3>1000){print $1,$3}else{print $3}}' /etc/passwd
6.数组 (awk 数组来计算 )
awk数组特性:
• awk的数组是关联数组(即key/value方式的hash数据结构),索引下标可为数值(甚至是负数、小数等),也可为字符串
1. 在内部,awk数组的索引全都是字符串,即使是数值索引在使用时内部也会转换成字符串 2. awk的数组元素的顺序和元素插入时的顺序很可能是不相同的
• awk数组支持数组的数组
7.相关面试题
1.提取下面的字段中的 IP地址和时间
58.87.87.99 - - [09/Jun/2020:03:42:43 +0800] "POST /wp-cron.php?doing_wp_cron=1591645363.2316548824310302734375 HTTP/1.1" ""sendfileon
128.14.209.154 - - [09/Jun/2020:03:42:43 +0800] "GET / HTTP/1.1" ""sendfileon
64.90.40.100 - - [09/Jun/2020:03:43:11 +0800] "GET /wp-login.php HTTP/1.1"""sendfileo
64.90.40.100 09/Jun/2020:03:43:11
cat access_log |awk '/2018:11:56:43/,/2018:11:56:44/{print $0}'
2.提取host.txt主机名后再放回host.txt文件
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
cat host.txt|awk '{print $2}'|awk -F'.' '{print $1}' >> host.txt
cat host.txt|awk -F '[ .]' '{print $2}' >>host.txt
3.统计/etc/fstab文件中每个文件系统类型出现的次数
cat /etc/fstab |awk '/^[^#]/{print $3}'|sort|uniq -c
4.统计/etc/fstab文件中每个真单词出现的次数
grep -Eo "\b[[:alpha:]]+\b" /etc/fstab |sort |uniq -c
5.提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中的所有数字
echo "Yd$C@M05MB%9&Bdh7dq+YVixp3vpw" |grep -o "[0-9]"
echo "Yd$C@M05MB%9&Bdh7dq+YVixp3vpw"|tr -cd "[0-9]"
6.提取主机名并放入原文件 test.txt
http://mail.kgc.com/index.html
http://www.kgc.com/test.html
http://study.kgc.com/index.html
http://blog.kgc.com/index.html
http://www.kgc.com/images/logo.jpg
http://blog.kgc.com/20080102.html
http://www.kgc.com/images/kgc.jpg
cat host.txt |awk -F[/.] '{print $3}'|sort -nr|uniq -c
7.查出/tmp/的权限,以数字方式显示
stat /tmp/|awk -F'[(/]' 'NR==4{print $2}'
8.查出用户UID最大值的用户名、UID及shell类型
cat /etc/passwd | sort -t: -k3 -n |tail -n1
二.sed
1.基本用法
sed [option]... 'script;script;...' [input file...]
选项 自身脚本语法 支持标准输入管道
常用选项:
-n 不输出模式空间内容到屏幕,即不自动打印
-e 多点编辑[root@www data]#sed -n -e '/^r/p' -e'/^b/p' /etc/passwd
-f FILE 从指定文件中读取编辑脚本
-r, -E 使用扩展正则表达式
-i.bak 备份文件并原处编辑
#说明: -ir 不支持-i -r 支持-ri 支持-ni 会清空文件
2.sed脚本格式
单引号中间需要写脚本;脚本格式如下
'地址+命令'组成
1. 不给地址:对全文进行处理(比如行号)
2. 单地址:
#:指定的行,$:最后一行
/pattern/:被此处模式所能够匹配到的每一行,正则表达式
3. 地址范围:
#,# #从#行到第#行,3,6 从第3行到第6行
#,+# #从#行到+#行,3,+4 表示从3行到第7行
/pat1/,/pat2/ 第一个正则表达式 到 第二个正则表达式之间的行
#,/pat/ 从#号行为开始找到 pat为止 3 , /^r/
/pat/,# 找到#号个pat为止
4. 步进:~
1~2 奇数行
2~2 偶数行
sed -n 'n;p' testfile1 #打印偶数行
sed -n '2,${n;p}' testfile1
命令
p 打印当前模式空间内容,追加到默认输出之后
Ip 忽略大小写输出
d 删除模式空间匹配的行,并立即启用下一轮循环
a [\]text 在指定行后面追加文本,支持使用\n实现多行追加
i [\]text 在行前面插入文本
c [\]text 替换行为单行或多行文本
w file 保存模式匹配的行至指定文件 seq 10 |sed -n '2wa.txt'
r file 读取指定文件的文本至模式空间中匹配到的行后 seq 10|sed '2r /etc/issue'
= 为模式空间中的行打印行号 sed '2=' /etc/passwd sed -n -e '=;p' /etc/passwd
! 模式空间中匹配行取反处理seq 10 |sed -n '1~2!p'
q 结束或退出sed seq 10 | sed '3q'
3.搜索替代
s/pattern/string/修饰符 查找替换,支持使用其它分隔符,可以是其它形式:s@@@,s###
替换修饰符:
g 行内全局替换
p 显示替换成功的行
w /PATH/FILE 将替换成功的行保存至文件中
I,i 忽略大小写
搜索替代之后项引用
[root@localhost ~]#echo 123abcxyz |sed -r 's/(123)(abc)(xyz)/\1/'
##分组 s//代表查找替换 ()代表分组 \1 代表留下的组
4.sed的高级用法
sed 中除了模式空间,还另外还支持保持空间(Hold Space),利用此空间,可以将模式空间中的数据,临时保存至保持空间,从而后续接着处理,实现更为强大的功能。
常见的高级命令
P 打印模式空间开端至\n内容,并追加到默认输出之前
h 把模式空间中的内容覆盖至保持空间中
H 把模式空间中的内容追加至保持空间中
g 从保持空间取出数据覆盖至模式空间
G 从保持空间取出内容追加至模式空间
x 把模式空间中的内容与保持空间中的内容进行互换
n 读取匹配到的行的下一行覆盖至模式空间
N 读取匹配到的行的下一行追加至模式空间
d 删除模式空间中的行
D 如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本,并不会读取新的输入行,而使
用合成的模式空间重新启动循环。如果模式空间不包含换行符,则会像发出d命令那样启动正常的新循环
例子:
sed -n 'n;p' FILE
seq 10 | sed 'N;s/\n//'
sed '1!G;h;$!d' FILE
seq 10 | sed -n '/3/{g;1!p;};h' #前一行
seq 10 | sed -nr '/3/{n;p}' #后一行
sed 'N;D'FILE
seq 10 |sed '3h;9G;9!d'
sed '$!N;$!D' FILE
sed '$!d' FILE
sed 'G' FILE
sed 'g' FILE
sed '/^$/d;G' FILE
sed 'n;d' FILE
sed -n '1!G;h;$p' FILE
范例: 打印偶数行
seq 10 | sed -n 'n;p'
seq 10 | sed -n '2~2p'
seq 10 | sed '1~2d'
seq 10 | sed -n '1~2!p'
5.相关面试题
1.提取版本号
ant-1.9.7.jar
ant-launcher-1.9.7.jar
antlr-2.7.7.jar
antlr-runtime-3.4.jar
aopalliance-1.0.jar
archaius-core-0.7.6.jar
asm-5.0.4.jar
aspectjweaver-1.9.5.jar
bcpkix-jdk15on-1.64.jar
bcprov-jdk15-1.46.jar
bcprov-jdk15on-1.64.jar
checker-compat-qual-2.5.5.jar
cat 1.txt |sed -r 's/.*-(.*)\.jar/\1/'
2.修改网卡名
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
#GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet net.ifnames=0"
#修改这行
GRUB_DISABLE_RECOVERY="true"
sed -ri.bak '/^GRUB_CMDLINE_LINUX/s#"$#net.ifnames=0"#' /etc/default/grub