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

posted @ 2023-02-21 18:05  wushaoyu  阅读(181)  评论(0编辑  收藏  举报