最典型的用法是,匹配指定字符串之间的字符。 比如,我们想在一句话(Hello,my name is aming.)中匹配中间的一段字符串(my name is) 可以这样写正则表达式。
# echo "Hello, my name is aming."|grep -P '(?<=Hello, ).*(?= aming.)'
如果只需要匹配到的部分,还可以加上-o选项
# echo "Hello, my name is aming."|grep -Po '(?<=Hello, ).*(?= aming.)'
根据这个思路,我们可以去匹配IP地址
# ifconfig eth0 |grep -Po '(?<=addr:).*(?= Bcast)'
例如:有个文件test的内容如下:
ert
fff
**
[abcfd]
123
324
444
[rty]
**
fgfgf
怎么能截取
[abcfd]
123
324
444
[rty]
这一部分出来呢?
#sed -n '/\[abcfd\]/,/\[rty\]/'p test (如果使用-rn 中间的逗号就不会起作用)
扩展:
# sed -n '/03\/Mar\/2016:02:52/,/03\/Mar\/2016:03:03:20/'p /usr/local/nginx/logs/cn.log |awk '{print $1}'|sort|uniq -c|sort -rn //查日志的时候非常有用
sed中,使用\u表示大写,\l表示小写
1. 把每个单词的第一个小写字母变大写:(\b后面例子)
# sed 's/\b[a-z]/\u&/g' filename
2. 把所有小写变大写:
# sed 's/[a-z]/\u&/g' filename
3. 大写变小写:
# sed 's/[A-Z]/\l&/g' filename
# sed -n "/abc\b/" file.log 里面这个\b是什么意思呢?
\b 是 boundary(边界) 的意思,表示单词到此结束,能够匹配 abc,但不匹配 abcd 等
方法1:# sed -n 'p;n' test.txt #奇数行
# sed -n 'n;p' test.txt #偶数行
方法2:# sed -n '1~2p' test.txt #奇数行
# sed -n '2~2p' test.txt #偶数行
#cat test
askdj
aslkd aslkdjf3e
skdjfsdfj
sdkfjk
fsdkfjksdjfkjsdf
12sdfesdf
aslkdjfkasdjf asdlfkjaskdfj
# sed 's/^a.*/& 12/g' test //以a开头的任何行,在其末尾添加 12
askdj 12
aslkd aslkdjf3e 12
skdjfsdfj
sdkfjk
fsdkfjksdjfkjsdf
12sdfesdf
aslkdjfkasdjf asdlfkjaskdfj 12
# sed -n '1,100{/abc/p}' 1.txt
# sed -n '1,100p' /etc/passwd | grep root
把passwd中第一个单词和最后一个单词调换位置:
# sed -r 's#([^:]+):(.*):([^:]+)#\3:\2:\1#g' passwd
把passwd中出现的第一个数字和最后一个单词替换位置:
# sed -r 's#([0-9]+):([0-9]+):([^0-9]+):(.*)/([^0-9]+)#\5:\2:\3:\4:\1#g' passwd
把passwd 中第一个数字移动到行末尾:
# sed -r 's#([0-9]+):([0-9]+):([^0-9]+):(.*)/([^0-9]+)#\2:\3:\4:\5:\1#g' passwd
在passwd 20行到末行最前面加 ‘aaa:’
# sed '20,$s/^/aaa: &/' passwd
grep 或 egrep 或awk 过滤两个或多个关键词:
# grep -E '123|abc' filename // 找出文件(filename)中包含123或者包含abc的行
# egrep '123|abc' filename //用egrep同样可以实现
# awk '/123|abc/' filename // awk 的实现方式
用awk编写生成以下结构文件的程序。( 最后列使用现在的时间,时间格式为YYYYMMDDHHMISS) 各列的值应如下所示,每增加一行便加1,共500万行。
1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,2005100110101
2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,2005100110101
#awk BEGIN{for(i=1;i<=10;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"))}'
解释:
%d:直接输出结果
%010d:输出以长度为10位数不足用0补足
strftime()函数的用法:
%Y 年
%m 月份
%d 日期
%H 小时
%M 分钟
strftime()的用法举例如下:
select strftime('%Y.%m.%d %H:%M:%S','now','localtime');
结果:2006.10.17 21:41:09
paste filename1 filename2
这样就可以实现了。举个例子。
cat a.txt
1 2 3
4 5 6
a b c
cat b.txt
3 2 1
6 5 4
c b a
则 paste a.txt b.txt 结果为
1 2 3 3 2 1
4 5 6 6 5 4
a b c c b a
如果,你想在两个文件连接处用一个指定的字符连接,还可以用-d来指定
paste -d '+' a.txt b.txt
结果为
1 2 3+3 2 1
4 5 6+6 5 4
a b c+c b a
/etc/passwd
显示第二行到第五行的行号和整行的内容:
# awk -F ':' 'NR>=2 && NR<=5 {print NR,$0}' /etc/passwd
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
显示从以bin开头的行,到第五行中的行号和整行内容:
[[email protected] awk]# awk -F ':' '/^bin/,NR==5 {print NR,$0}' /etc/passwd
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
从第五列以bin开始的行到以lp开头的行并显示其行号和整行内容:
[[email protected] awk]# awk -F ':' '$5 ~ /^bin/,/^lp/ {print NR,$0}' /etc/passwd
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
统计/etc/servies文件里的空行数量:
[[email protected] awk]# grep "^$" /etc/services | wc -l
16
[[email protected] awk]# grep -c "^$" /etc/services
16
取eth0的IP地址:
[[email protected] awk]# # ifconfig ens33 | awk -F "[^0-9.]+" 'NR==2{print $2}'
192.168.197.133