sed awk的使用
shell中数值运算:
expr 、$[] 、let
一、sed使用
格式:sed 【选项】 ‘条件指令’ 文件
逐行读取处理
常用选项: -n:屏蔽默认输出,默认sed会输出读取文件的全部内容 -r:让sed支持扩展正则 -i:直接修改源文件,默认sed知识通过内存临时修改文件并且输出到当前终端,对源文件无影响
-e:可以在同一行里执行多条指令 条件指令: d:删除指定行 p:打印指定行,输出到屏幕 s:按条件替换内容 c:替换指定行 a:在指定行后面追加文本 i:在指定航前面追加文本
g:全局替换
():保留整体
例:
1)基础选项的使用
1 sed -n ‘3,6p' /etc/passwd 输出3到6行的内容 2 sed -n '3p;6p' /etc/passwd 输出第3行和第6行的内容 3 sed -n ’1,3d' /etc/passwd 删除第1到3行(并没有真的修改源文件,只做临时输出) 4 sed ‘s/root/wsy/' /etc/passwd 把文件/etc/passwd文件中的root替换为wsy,只替换每一行的第一个root 5 sed -n ’s/root/wsy/p' /etc/passwd 全局替换且只显示替换的行 6 sed ‘2a xx’ a.txt 在a.txt文件的第2行后面写入xx
2)当一步实现不了时,可以分为2步来实现,中间用;分隔
sed -r 's/[0-9]//g;s/^( )+//' a.txt 删除文件中所有数字和行首的空格
3)-e选项,同一行里执行多条命令
sed -e 's/11/10/g' -e 's/22/99/g' a.txt #-e选项,2个s替换都执行,不加只执行前一个
4)整体替换追加。在同一行的内容后面追加内容,可以用扩展正则来替换
将文件中每行的第一个、倒数第1个字符互换每行文本拆分为“第1个字符”、“中间的所有字符”、“倒数第1个字符”三个部分,然后通过替换操作重排顺序为“3-2-1”:
[ root@sv r5 ~] # sed -i -r 's/^(LogFile=).*/\1\/home\/admin\/zabbix.txt/' test.txt
[ root@sv r5 ~] # sed - r 's/^( .) ( .*) ( .) $/\3\2\1/' nssw.txt
[root@localhost ~]# sed -r -i "s@(/dev/mapper/ora_data-data_lv)@\1 $a@" a.txt Filesystem Size Used Avail Use% Mounted on /dev/sda5 30G 5.2G 23G 19% / tmpfs 32G 568K 32G 1% /dev/shm /dev/sda2 488M 38M 425M 9% /boot /dev/sda1 200M 264K 200M 1% /boot/efi /dev/sda3 50G 15G 33G 31% /opt /dev/sda6 715G 401G 278G 60% /databak /dev/mapper/ora_data-data_lv 493G 36G 432G 8% /data /dev/mapper/ora_data-data1_lv /dev/mapper/ora_data-datafile_lv 493G 36G 432G 8% /data 296G 122G 159G 44% /data1 493G 164G 304G 36% /datafile
5)替换内容
[root@redhat6 ~]# cat b.txt <th scope="col">TRIGGER_NAME</th> [root@redhat6 ~]# sed -e 's/<[^>]*>//g' b.txt #[]为集合内任意字符,[^]对任意字符取反,对>取反后面有>,*是<>内的全部内容 TRIGGER_NAME
按条件替换内容
sed -n '/bash$/s/\bin\bash/\/abc/g' /etc/passwd 把/etc/passwd这个文件的以bash结尾的行的/bin/bash替换为/abc
提取以bash结尾行的用户名
sed -n '/bash$/s/:.*//p' /etc/passwd
把文件的行首空格删除,左对齐并把大写字母加上()
sed -r 's/^( )+/ /;s/([A-Z])/(\1)/' a.txt
删除文件中的空行
sed ’/^$/d' a.txt
替换文本中第二个出现的aa为bb
sed -i 's/aa/bb/2' a.txt
可学习的sed详解实例:https://www.cnblogs.com/ctaixw/p/5860221.html
6、sed从日志中获取指定时间戳内的日志
sed -n ‘/2015-05-04 09:25:55/,/2015-05-04 09:28:55/p’ logfile
https://www.cnblogs.com/alexyuyu/p/6376200.html
二、awk使用
选项:awk -F [ 选项] ‘[条件】{指令}’ 文件
print为常用指令,若有多条可用;分隔,awk过滤数据支持打印某一列,若没有指定分隔符,则默认将空格 制表符作为分隔符
1、awk内置变量:
$0:文本当前行的全部内容 $1:文本的第1列 $NF:文本的最后一列 NR:文件当前行的行号 NF:文件当前行的行数 $(NF-1):倒数第2列
2、awk内置函数:
split 初始化和类型强制:awk的内建函数split允许你把一个字符串分隔为单词并存储在数组中。你可以自己定义域分隔符或者使用现在FS(域分隔符)的值
格式:
split (string, array, field separator)
split (string, array)
-->如果第三个参数没有提供,awk就默认使用当前FS值
例:
[root@iZ2ze6rm1auwacy4tk6ucaZ ~]# all_ip=192.168.121.131,192.168.121.135 [root@iZ2ze6rm1auwacy4tk6ucaZ ~]# awk 'BEGIN{iplist="'$all_ip'";split(iplist,ip,",");for (s in ip){print ip[s]}}' 192.168.121.131 192.168.121.135 或 [root@iZ2ze6rm1auwacy4tk6ucaZ ~]# echo $all_ip|awk '{split($1,ip,",");for (s in ip){print ip[s]}}' 192.168.121.131 192.168.121.135
效果图:
substr 截取字符串:返回从起始位置起,指定长度之子字符串;若未指定长度,则返回从起始位置到字符串末尾的子字符串。
格式:
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分
解释:
awk -F ',' '{print substr($3,6)}' ---> 表示是从第3个字段里的第6个字符开始,一直到设定的分隔符","结束.
substr($3,10,8) ---> 表示是从第3个字段里的第10个字符开始,截取8个字符结束.
substr($3,6) ---> 表示是从第3个字段里的第6个字符开始,一直到结尾
length 字符串长度:length函数返回没有参数的字符串的长度。length函数返回整个记录中的字符数
例:
#substr应用 [root@localhost ~]# cat /etc/passwd |awk -F: '{print substr($(NF-1),1,5)}' #截取倒数第二列,从它的第1个字符开始,到第5个字符结束 [root@localhost ~]#BEGIN_LINE=cat `$PWD/alert_CCXE.log|grep -n "$TODAY"|awk '{print substr($1,1,length($1)-4) NR "z" NR "z" }'|grep '1z1z'|awk '{print substr($1,1,length($1)-4)}'` #awk的算数运用 TOTAL_LINE=15236 BEGIN_LINE=12597 TAIL_LINES=`echo "$TOTAL_LINES $BEGIN_LINE"|awk '{ {s=$1-$2+1} {print s} }'`
gsub函数:gsub函数则使得在所有正则表达式被匹配的时候都发生替换。gsub(regular expression, subsitution string, target string);简称 gsub(r,s,t)
例:
内容:/dev/cciss/c0d0p6 211G 104G 97G 52% /data [root@localhost ~]# df -h |grep "/data" |awk 'gsub(/%/,"",$5){print $5}' #正则匹配%,替换为空"",目标字段$5
aws sum函数:
cat data|awk '{sum+=$1} END {print "Sum = ", sum}'
注:NR可显示当前行号
3、awk打印常量需要引用双引号
#df -h |awk '{print "lujing",$NF}'
4、awk支持正则
awk -F: '/bash$/{print}' /etc/passwd
awk -F: '$1~/root/{print $7}' /etc/passwd
awk -F: 'NR==3{print $3}' /etc/passwd
ps -ef |awk -F '[ :]' '{print $(NF-1)}' |xrags kill -9
5、awk数据(先排序,在去重。uniq去重只能统计相邻的重复值,而sort可以是相同的都放在同一行)
遍历数组:for(变量 in 数组名){print 数组名【变量】} 公式: awk ‘{ip[$i]++}END{for(i in ip){print ip[i],i}}' file |sort -nr |uniq -c|column -t
[root@localhost ~]# du -sh ./* |awk '{a+=$1}END{print a}' 1853.6
可取出其一列所有数之和
6、正则匹配部分可以用变量代替
[root@localhost ~]# name=TIME_WAIT
[root@localhost ~]# netstat -n | awk -F '[ :]+' '/TIME_WAIT/ {++S[$(NF-3)]} END {for(a in S) print a,"次数",S[a]}'
127.0.0.1 次数 1
10.2.2.44 次数 3
192.168.100.203 次数 2
[root@localhost ~]# netstat -n | awk -F '[ :]+' '/$name/ {++S[$(NF-3)]} END {for(a in S) print a,"次数",S[a]} #此处正则匹配可以使用变量代替,需’“$name"'代替
方法如下:
[root@localhost ~]# netstat -n | awk -F '[ :]+' '/'"$name"'/ {++S[$(NF-3)]} END {for(a in S) print a,"次数",S[a]}'
#里面双引、外面单引
可参考学习:https://www.cnblogs.com/ginvip/p/6376049.html