在上一帖的实战中,我们用到了grep的"-Po"的用法。首先,我们来看看这几个参数的含义:
-P,--perl-regexp InterpretPATTERNasaPerlregularexpression.Thisishighly experimentalandgrep-Pmaywarnofunimplementedfeatures. -o,--only-matching Printonlythematched(non-empty)partsofamatchingline,witheachsuchpartonaseparateoutputline.
“-P”表示采用的模式是Perl正则表达式的模式,“-o”表示只需要匹配到的内容。
像这种参数在平时是很少使用的,需要经常翻看命令手册和实例,熟悉这些用法,以备不时之需。
下面整理了几个非主流实例,通过实例熟悉下sed和awk的扩展用法。
sed
1、打印某行到某行之间的内容
[root@server01test2]#sed-n'/lp/,/shutdown/'ppasswd lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
2、转换大小写
使用\u表示大写,\l表示小写
�把每个单词的第一个小写字母变大写:
[root@server01test2]#sed's/\b[a-z]/\u&/g'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@server01test2]#sed's/[a-z]/\u&/g'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@server01test2]#sed's/[A-Z]/\l&/g'/etc/logrotate.conf ...... #rpmpackagesdroplogrotationinformationintothisdirectory include/etc/logrotate.d ......
3、在某一行最后添加字符串
[root@server01test2]#sed's/\(^shutdown.*\)/\1123abc/'passwd|grepshutdown shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown123abc
4、删除某行到最后一行
[root@server01test2]#sed'/shutdown/{p;:a;N;$!ba;d}'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 adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
定义一个标签a,匹配shutdown这个关键词,然后N把下一行加到模式空间里,匹配最后一行时,才退出标签循环,然后命令d,把这个模式空间里的内容全部清除。
5、打印某行到某行含某个字符串的行
[root@server01test2]#sed-n'1,10{/nologin/p}'passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin
awk
1、使用外部shell变量
[root@server01test2]#A=100 [root@server01test2]#echo"ABCD"|awk-vGETA=$A'{printGETA}' 100
2、合并一个文件
�第一列相同的行合并到同一行中:
[root@server01test2]#cata.txt 1a1 2a2 3a3 4a4 [root@server01test2]#catb.txt 1b1 2b2 3b3 4b4 [root@server01test2]#awk'NR==FNR{a[$1]=$2}NR>FNR{print$0,a[$1]}'a.txtb.txt 1b1a1 2b2a2 3b3a3 4b4a4
NR表示读取的行数,FNR表示读取的当前行数。
所以其实NR==FNR,就表示读取b.txt的时候。 同理NR>FNR表示读取a.txt的时候。
数组a其实就相当于一个map。
3、把一个文件多行连接成一行
[root@server01test2]#a=`cata.txt`;echo$a 1a12a23a34a4 [root@server01test2]#awk'{printf("%s",$0)}'a.txt 1a12a23a34a4 [root@server01test2]#cata.txt|xargs 1a12a23a34a4
4、gsub函数
[root@server01test2]#grep'root'passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@server01test2]#awk'gsub(/root/,"abc")'passwd abc:x:0:0:abc:/abc:/bin/bash operator:x:11:0:operator:/abc:/sbin/nologin
�用awk编写生成以下结构文件的程序。( 最后列使用现在的时间,时间格式为YYYYMMDDHHMISS)各列的值应如下所示,每增加一行便加1,共500万行。
1,1,0000000001,2005100110101
2,2,0000000002,2005100110101
[root@server01test2]#awk'BEGIN{for(i=1;i<=5000000;i++)printf("%d,%d,%010d,%d\n",i,strftime("%Y%m%d%H%M"))}' 1,201706282126 2,201706282126 3,3,0000000003,201706282126 4,4,0000000004,201706282126 5,5,0000000005,201706282126 6,6,0000000006,201706282126 7,7,0000000007,201706282126 8,8,0000000008,201706282126 9,9,0000000009,201706282126 10,10,0000000010,201706282126 ......
6、用print打印单引号
[root@server01test2]#awk'{print"'"'"'"$1}'a.txt '1 '2 '3 '4
在awk中使用脱义字符\是起不到作用的,如果想打印特殊字符,只能使用'""'这样的组合才可以。
这里自左至右为单引号 双引号 双引号 单引号。其中两个单引号为一对,两个双引号为一对。想脱义$那就是'"$"' 脱义单引号那就是 '"'"'。
7、提取eth0的IP信息
[root@server01test2]#ifconfigens33 ens33:flags=4163<UP,BROADCAST,RUNNING,MULTICAST>mtu1500 inet192.168.137.100netmask255.255.255.0broadcast192.168.137.255 inet6fe80::c1d7:5856:9856:2bb8prefixlen64scopeid0x20<link> ether00:0c:29:0c:4d:a8txqueuelen1000(Ethernet) RXpackets160327bytes130100204(124.0MiB) RXerrors0dropped0overruns0frame0 TXpackets88376bytes52770231(50.3MiB) TXerrors0dropped0overruns0carrier0collisions0 [root@server01test2]#ifconfigens33|awk-F"[^0-9.]+"'NR==2{print$2,$3,$4}' 192.168.137.100255.255.255.0192.168.137.255
8、合并两个文件
[root@server01test2]#pastea.txtb.txt 1a11b1 2a22b2 3a33b3 4a44b4 [root@server01test2]#paste-d'+'a.txtb.txt 1a1+1b1 2a2+2b2 3a3+3b3 4a4+4b4