您的位置:首页 > 运维架构 > Linux

Linux_note 命令grep,sed,awk

2016-01-09 20:36 579 查看
1、grep 过滤出指定的行
grep [-cinvABC] 'word' filename
--color 把匹配到的关键词用红色标识 如:# grep --color 'root' /etc/passwd

-c :打印符合要求的行数

-i :忽略大小写

-n :在输出符合要求的行的同时连同行号一起输出

-v :打印不符合要求的行# cg -v 'root' 1.txt

-A :后跟一个数字(有无空格都可以),例如 朅2则表示打印符合要求的行以及下面两行
# cg -A 2 -n 'root' 1.txt
-B :后跟一个数字,例如 B 2 则表示打印符合要求的行以及上面两行# cg -B 2 -n 'root' 1.txt

-C :后跟一个数字,例如 C 2 则表示打印符合要求的行以及上下各两行# cg -C 2 -n 'root' 1.txt
-r :将目录下所有文件全部遍历 # cg -r 'iptables' /etc/* 或# cg -rh 'iptables' /etc/*
[root@zekLinux ~]# alias cg='grep --color'
[root@zekLinux ~]# cg -n 'root' 1.txt
1:root:x:0:0:root:/root:/bin/bash
11:operator:x:11:0:operator:/root:/sbin/nologin
[root@zekLinux ~]# cg -c 'root' 1.txt
2
[root@zekLinux ~]# cg -A 2 -n 'root' 1.txt
1:root:x:0:0:root:/root:/bin/bash
grep sed 都是支持 {1,3}这样的匹配规则的,表示重复前面字符1到3次。但是awk属于一个比较复杂的脚本语

言,在它里面()和{}都是有特殊含义的,所以我们要使用这些符号时,需要给他们脱义,你可能会想到使用\脱

义,但是不管用。有一个方法就是加上--posix选项就ok ,比如
awk --posix -F ':' '$1 ~ /(ab)+|o{1,3}/' 1.txt
这样就可以把B选项匹配出来
2-bin:x:1:1:bin:/bin:/sbin/nologin
3-daemon:x:2:2:daemon:/sbin:/sbin/nologin
--
11:operator:x:11:0:operator:/root:/sbin/nologin
12-games:x:12:100:games:/usr/games:/sbin/nologin
13-gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
[root@zekLinux ~]# cg -B 2 -n 'games' 1.txt
10-uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
11-operator:x:11:0:operator:/root:/sbin/nologin
12:games:x:12:100:games:/usr/games:/sbin/nologinli

例子:
过滤出带有某个关键词的行并输出行号
# cg -n 'aming' 1.txt 或者grep -n --color 'aming' 1.txt cg= 'grep --color '
过滤出带有某个关键词的行并输出行号
# cg -v -n 'nologin' 1.txt
过滤出所有包含数字的行
#cg -n '[0-9]' 1.txt
过滤出包含某个字母的行并输出行号
# cg -n '[aN]' 1.txt
#cg -n -i '[aN]' 1.txt
过滤出不包含字母的行并输出行号
[root@zekLinux ~]# grep --color -n -v '[a-zA-Z]' 1.txt
22:$%$#%@^&&*()^%#!@#%^&*((*&^%$#@!%((*&^%$#@@***&^%
23:
33:34988385983402474023572647346348324623768329
去除以字母开头的行
[root@zekLinux ~]# cg -n -v '^[a-zA-Z]' 1.txt
22:$%$#%@^&&*()^%#!@#%^&*((*&^%$#@!%((*&^%$#@@***&^%
23:
33:34988385983402474023572647346348324623768329
过滤出不以数字开头的行
#cg -n '^[^0-9]' 1.txt
匹配出不包含数字的行
#cg -n '[^0-9]' 1.txt
去除空行
[root@zekLinux ~]# grep -v '^$' 1.txt
过滤任意一个或多个字符
#cg 'r.o' 1.txt
# cg 'r*o' 1.txt
#cg 'r*o' 1.txt 匹配出r开头o结尾的字符,中间是什么不重要,也叫贪婪匹配。
. 表示任意一个字符
* 表示零个或多个前面的字符
.* 表示零个或多个任意字符,空行也包含在内
grep 'r\?o' passwd 表示匹配零个或一个前面为“r”的字符。
grep 'r.*o' passwd 表示r开头o结尾,中间零个或多个任意字符
grep 'r*o' passwd 匹配匹配零个或多个前面的字符。这个前面的字符是“r”,可以是0个r或者多个r
grep '^[1-9][0-9]*$' 1.txt:匹配开头为1到9其中一个数字,结尾是0个或多个数字

过滤出以特殊符号开头的行
[root@zekLinux ~]# cg -n '^[^0-9a-zA-Z]' 1.txt
22:$%$#%@^&&*()^%#!@#%^&*((*&^%$#@!%((*&^%$#@@***&^%

egrep ==grep -E egrep时grep的扩展形式 egrep能用的grep全都能用
grep --color 'r\?o' 1.txt==grep --color -E 'r?o' 1.txt==egrep --color 'r?o' 1.txt
匹配1个和1个以上+前面的字符
# egrep --color 'r+o' 1.txt
总结:. 任意一个字符;* 零个或多个*前面的字符; .* 任意个任意字符; ? 0或1个?前面的字符;+ 1或多

个+前面的字符。
匹配root或nologin
#egrep --color 'root|nologin' 1.txt
匹配root和nologin
# grep --color 'root' 1.txt |grep --color 'nologin'
用括号表示一个整体
#egrep --color '(rr)' 1.txt
匹配1个或多个rr
#egrep --color '(rr)+' 1.txt
指定匹配字符次数范围
# egrep --color '(rr){1,3} 1.txt
? + () {} | 符号要用egrep。

2、sed
打印指定的行
# sed -n '10'p 1.txt
打印指定范围,如20行到末
# sed -n '20,$'p 1.txt
打印包含某个字符串的行
# sed -n '/root/'p 1.txt
可以使用^ . * $ + ? 等特殊符号
# sed -n '/r.o/'p 1.txt
# sed -n '/r*o/'p 1.txt
# sed -n '/r.*o/'p 1.txt
# sed -n '/r\?o/'p 1.txt
# sed -n '/r\+o/'p 1.txt
# sed -n '/root\|nologin/'p 1.txt
# sed -n '/\(oo\)\+/'p 1.txt
-r不需要脱意符号
# sed -n -r '/(oo)+/'p 1.txt
# sed -n -r '/[^0-9]/'p 1.txt
# sed -n -r '/[^a-zA-Z]/'p 1.txt
空行
# sed -n -r '/^$/'p 1.txt
删除空行
# sed '/^$/'d 1.txt
删除包含数字的行
# sed '/[0-9]/'d 1.txt
删除包含字母的行
# sed '/[a-zA-Z]/'d 1.txt
删除指定行,如删除1-19行
# sed '/1,19/'d 1.txt
上述删除并没有直接删除文件内容只是在显示器上不显示。sed -i 选项就会将文件内容删除
[root@zekLinux ~]# wc -l 2.txt
33 2.txt
[root@zekLinux ~]# sed -i '1,19'd 2.txt
[root@zekLinux ~]# wc -l 2.txt
14 2.txt

替换功能
# sed '1,10s/nologin/login/g' 1.txt
含有特殊符号需脱意\ 如:# sed '1,10s/\/sbin\/nologin/login/g' 2.txt也可以替换为
# sed'1,10s@/sbin/nologin@logi@g' 2.txt
替换一整行
# sed '1,5s#^.*$#login#g' 2.txt
在尾部加上某字符串,如login
# sed '1,5s#^.*$#& login#g' 2.txt
将每行的数字删除
# sed 's#[0-9]##g' 2.txt
将除字母数字之外的字符删除
# sed 's#[^0-9a-zA-Z]##g' 2.txt
将每一行的第一段与最后一段交换
# sed -r 's#^([a-z]+)(:.*:)(.*$)#\3\2\1#g' 2.txt
# sed -r 's/([^:]+)(:.*:)([^:]+)/\3\2\1/' /etc/passwd
理解:sed -r 's/([^:]+)(:.*:)([^:]+)/\3\2\1/' /etc/passwd // 匹配第一段除":"的任意字符 匹配第二段

":任意字符: "第三段 也是除开":"的任意字符 \3\2\1 相当于把第一段和第三段对调
第一个字符与最后一个字符交换
sed -r 's/^(.)(.*)(.)$/\3\2\1/'
[root@zekLinux ~]# echo "abcdef"|sed -r 's/^(.)(.*)(.)$/\3\2\1/'
fbcdea

同时进行多个任务; -e
# sed -n '/root/p;/aming/'p 1.txt或者# sed -n -e '/root/p' -e '/aming/p' 1.txt
;特殊性若遇到一行既有root又有aming会打印两行,不同于|,|或只打印一行,;的意思是匹配到就打印。
[root@zekLinux ~]# sed -n -r '/root|aming/'p 1.txt
root: aming x:0:0:root:/root:/bin/bash
operatorrrrro:x:11:0:operator:/root:/sbin/nologin
aming123:x:501:513::/home/aming123:/bin/bash
[root@zekLinux ~]# sed -n '/root/p; /aming/p' 1.txt
root: aming x:0:0:root:/root:/bin/bash
root: aming x:0:0:root:/root:/bin/bash
operatorrrrro:x:11:0:operator:/root:/sbin/nologin
aming123:x:501:513::/home/aming123:/bin/bash

3、awk 命令 截取文段中的某段
-F 指定分隔符号为: 若分隔符号为特殊符号则用单引号' '
打印某段字符
# awk -F ':' '{print $3}' 1.txt
# awk -F ':' '{print $3,$4}' 1.txt
显示指定字符
# awk -F ':' 'OFS=":" {print $3,$4}' 1.txt
# awk -F ':' 'OFS="#" {print $3,$4}' 1.txt
匹配字符或字符串
# awk '/r/' 1.txt
# awk '/root|user/' 1.txt
 awk '/r*o/' 1.txt
# awk '/r?o/' 1.txt
# awk '/r+o/' 1.txt
# awk '/r.*o/' 1.txt
匹配一个整体
# awk '/(oo)/' 1.txt
# awk '/(oooo)+/' 1.txt
按段匹配
# awk -F ':' '$1~/r*o/' 1.txt
# awk -F ':' '$1~/r*o/ {print $4}' 1.txt
多次匹配
# awk -F ':' '$1~/r*o/ {print $1,$3}; $1~/user/ {print $1,$3}' 1.txt
若匹配时匹配要求同时满足时将打印两次(awk属于流式编辑器)
[root@zekLinux ~]# awk -F ':' '$1~/r*o/ {print $1,$4};$1~/nobody/ {print $1,$4}' 1.txt
rooooooooot 0
daemon 2
shutdown 0
operator 0
gopher 30
nobody 99
nobody 99
postfix 89
avahi-autoipd 170
haldaemon 68
[root@zekLinux ~]# awk -F ':' '$1~/r*o|nobody/ {print $1,$4}' 1.txt
rooooooooot 0
daemon 2
shutdown 0
operator 0
gopher 30
nobody 99
postfix 89
avahi-autoipd 170
haldaemon 68

awk 条件操作符 ==,>,<,>=,!=;<=
# awk -F ':' '$1=="nobody"' 1.txt
nobody:x:99:99:Nobody:/:/sbin/nologin
# awk -F ':' '$1=="nobody"|| $1~/nolog/' 1.txt
# awk -F ':' '$4>=500' 1.txt
# awk -F ':' '$7!="/sbin/nologin"' 1.txt
匹配
# awk -F ':' '$7~/nolog/' 1.txt
# awk -F ':' '$7!~/nolog/' 1.txt
比较
# awk -F ':' '$3<$4' 1.txt
# awk -F ':' 'OFS=":";$3=$4' 1.txt
# awk -F ':' '$3==$4' 1.txt
# awk -F ':' 'OFS=":";{if($4>5){$7=$3+$4}}' 1.txt
以空白字符为分隔符,把第一段等于'aming'并且第3段小于100的行过滤出来。(首先得有以空白字符为分隔符

的文件)
[root@zekLinux ~]# sed -i 's/:/ /g' 2.txt
[root@zekLinux ~]# awk '$1=="games" && $3<100' 2.txt
games x 12 100 games /usr/games /sbin/nologin

awk 内置变量 NF(段数) NR(行数)
# awk -F ':' 'NR==10' 1.txt 打印第十行
# awk -F ':' 'NR>10' 1.txt 打印10行以后的行
# awk -F ':' 'NR<10' 1.txt
[root@zekLinux ~]# awk -F ':' 'NR==10 {print $1,$7}' 1.txt
uucp /sbin/nologin
[root@zekLinux ~]# awk -F ':' 'OFS=":"{if (NR==10) print $1,$7}' 1.txt
uucp:/sbin/nologin
[root@zekLinux ~]# awk -F':' '{print NF}' 1.txt
[root@zekLinux ~]# awk -F':' '{if (NF==7) print $1}' 1.txt
# awk -F':' '{print $NR,$NF}'
NR是根据行在变化的,而NF就是这一行一共有多少段。
# awk -F ':' 'NR==10 {OFS="#";print $1,$7}' 1.txt
awk也可以经行数学运算
[root@zekLinux ~]# awk -F':' '$7=$3+$4' 1.txt
bin x 1 1 bin /bin 2
daemon x 2 2 daemon /sbin 4
adm x 3 4 adm /var/adm 7
lp x 4 7 lp /var/spool/lpd 11
sync x 5 0 sync /sbin 5
shutdown x 6 0 shutdown /sbin 6
halt x 7 0 halt /sbin 7
默认以空白符以分割符,若一个文本文档某一段发生了改变打印时就会默认以空白符为分隔符。需要用OFS来指

定分隔符。
[root@zekLinux ~]# awk -F':' 'OFS=":" {$7=$3+$4; print $0}' 1.txt
rooooooooot:x:0:0:root:/root:0
bin:x:1:1:bin:/bin:2
daemon:x:2:2:daemon:/sbin:4
adm:x:3:4:adm:/var/adm:7
lp:x:4:7:lp:/var/spool/lpd:11
sync:x:5:0:sync:/sbin:5
# awk -F':' 'OFS=":" {$7=$3+$4; print $1,$3}' 1.txt
计算某一段的总和,如第三段$3
[root@zekLinux ~]# awk -F':' '{sum=sum+$3};END {print sum}' 1.txt
4807
[root@zekLinux ~]# awk -F':' '{(sum=sum+$3)};END {print sum}' 1.txt
4807

{}
awk结构: awk -F ':' 'BEGIN{OFS=“:”} {if(条件){语句1;语句2;语句3}} END{语句}'
参考教程 http://www.cnblogs.com/emanlee/p/3327576.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  sed grep awk