在上一帖的实战中,我们用到了grep的"-Po"的用法。首先,我们来看看这几个参数的含义:
1
2
3
4
5
6
7
|
-P, --perl-regexp
Interpret PATTERN as a Perl regular expression. This is highly
experimental and grep -P may warn of unimplemented features.
-o, --only-matching
Print only the matched (non-empty) parts of a matching line,
with each such part on a separate output line.
|
“-P”表示采用的模式是Perl正则表达式的模式,“-o”表示只需要匹配到的内容。
像这种参数在平时是很少使用的,需要经常翻看命令手册和实例,熟悉这些用法,以备不时之需。
下面整理了几个非主流实例,通过实例熟悉下sed和awk的扩展用法。
sed
1、打印某行到某行之间的内容
1
2
3
4
|
[root@server01 test2]
# sed -n '/lp/,/shutdown/'p passwd
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表示小写
▼把每个单词的第一个小写字母变大写:
1
2
3
4
5
|
[root@server01 test2]
# 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
......
|
▼把所有小写变大写:
1
2
3
4
5
|
[root@server01 test2]
# 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
......
|
▼大写变小写:
1
2
3
4
5
|
[root@server01 test2]
# sed 's/[A-Z]/\l&/g' /etc/logrotate.conf
......
# rpm packages drop log rotation information into this directory
include
/etc/logrotate
.d
......
|
3、在某一行最后添加字符串
1
2
|
[root@server01 test2]
# sed 's/\(^shutdown.*\)/\1 123abc/' passwd | grep shutdown
shutdown
:x:6:0:
shutdown
:
/sbin
:
/sbin/shutdown
123abc
|
4、删除某行到最后一行
1
2
3
4
5
6
7
8
|
[root@server01 test2]
# 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、打印某行到某行含某个字符串的行
1
2
3
4
5
6
7
|
[root@server01 test2]
# 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变量
1
2
3
|
[root@server01 test2]
# A=100
[root@server01 test2]
# echo "ABCD" | awk -v GETA=$A '{print GETA}'
100
|
2、合并一个文件
▼第一列相同的行合并到同一行中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[root@server01 test2]
# cat a.txt
1 a1
2 a2
3 a3
4 a4
[root@server01 test2]
# cat b.txt
1 b1
2 b2
3 b3
4 b4
[root@server01 test2]
# awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}' a.txt b.txt
1 b1 a1
2 b2 a2
3 b3 a3
4 b4 a4
|
NR表示读取的行数,FNR表示读取的当前行数。
所以其实NR==FNR,就表示读取b.txt的时候。 同理NR>FNR表示读取a.txt的时候。
数组a其实就相当于一个map。
3、把一个文件多行连接成一行
1
2
3
4
5
6
|
[root@server01 test2]
# a=`cat a.txt`;echo $a
1 a1 2 a2 3 a3 4 a4
[root@server01 test2]
# awk '{printf("%s ",$0)}' a.txt
1 a1 2 a2 3 a3 4 a4
[root@server01 test2]
# cat a.txt |xargs
1 a1 2 a2 3 a3 4 a4
|
4、gsub函数
1
2
3
4
5
6
|
[root@server01 test2]
# grep 'root' passwd
root:x:0:0:root:
/root
:
/bin/bash
operator:x:11:0:operator:
/root
:
/sbin/nologin
[root@server01 test2]
# awk 'gsub(/root/,"abc")' passwd
abc:x:0:0:abc:
/abc
:
/bin/bash
operator:x:11:0:operator:
/abc
:
/sbin/nologin
|
5、生成特殊结构文件
▼用awk编写生成以下结构文件的程序。( 最后列使用现在的时间,时间格式为YYYYMMDDHHMISS) 各列的值应如下所示,每增加一行便加1,共500万行。
1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,2005100110101
2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,2005100110101
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@server01 test2]
# awk 'BEGIN{for(i=1;i<=5000000;i++)printf("%d,%d,%010d,%010d,%010d,%010d,%010d,%010d,%d\n",i,i,i,i,i,i,i,i,strftime("%Y%m%d%H%M"))}'
1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,201706282126
2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,201706282126
3,3,0000000003,0000000003,0000000003,0000000003,0000000003,0000000003,201706282126
4,4,0000000004,0000000004,0000000004,0000000004,0000000004,0000000004,201706282126
5,5,0000000005,0000000005,0000000005,0000000005,0000000005,0000000005,201706282126
6,6,0000000006,0000000006,0000000006,0000000006,0000000006,0000000006,201706282126
7,7,0000000007,0000000007,0000000007,0000000007,0000000007,0000000007,201706282126
8,8,0000000008,0000000008,0000000008,0000000008,0000000008,0000000008,201706282126
9,9,0000000009,0000000009,0000000009,0000000009,0000000009,0000000009,201706282126
10,10,0000000010,0000000010,0000000010,0000000010,0000000010,0000000010,201706282126
......
|
6、用print打印单引号
1
2
3
4
5
|
[root@server01 test2]
# awk '{print "'"'"'"$1}' a.txt
'1
'2
'3
'4
|
在awk中使用脱义字符\是起不到作用的,如果想打印特殊字符,只能使用'""'这样的组合才可以。
这里自左至右为单引号 双引号 双引号 单引号。其中两个单引号为一对,两个双引号为一对。想脱义$那就是'"$"' 脱义单引号那就是 '"'"'。
7、提取eth0的IP信息
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@server01 test2]
# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.137.100 netmask 255.255.255.0 broadcast 192.168.137.255
inet6 fe80::c1d7:5856:9856:2bb8 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:0c:4d:a8 txqueuelen 1000 (Ethernet)
RX packets 160327 bytes 130100204 (124.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 88376 bytes 52770231 (50.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@server01 test2]
# ifconfig ens33 | awk -F "[^0-9.]+" 'NR==2{print $2,$3,$4}'
192.168.137.100 255.255.255.0 192.168.137.255
|
8、合并两个文件
1
2
3
4
5
6
7
8
9
10
|
[root@server01 test2]
# paste a.txt b.txt
1 a1 1 b1
2 a2 2 b2
3 a3 3 b3
4 a4 4 b4
[root@server01 test2]
# paste -d '+' a.txt b.txt
1 a1+1 b1
2 a2+2 b2
3 a3+3 b3
4 a4+4 b4
|
本文转自Grodd51CTO博客,原文链接:http://blog.51cto.com/juispan/1945455,如需转载请自行联系原作者