首页 > 代码库 > grep、sed、awk基础

grep、sed、awk基础

grep

grep :根据模式,搜索文本,并将符合模式的文本行显示出来,

使用基本正则表达式定义的模式来过滤文本的命令:

-i :忽略大小写

--color :加上颜色,

-v :显示没有被模式匹配到的行

-n:显示匹配到的行在文件中的行数

-w:精确匹配,只匹配整个单词,而不是字符串的一部分

-o :只显示被模式匹配到的字符串

-A #:after, 后#行

-B #: before, 前#行

-C #:context, 前后各#行

-c:显示一个文件被匹配到几行

-E :使用扩展正则表达式

-l:只列出匹配到的文件名

-L:列出不匹配的文件名,

grep -f file1 file2:显示file2中包含file1中的行

元字符:

. :匹配任意单个字符

[ ] :匹配指定范围内的任意单个字符

[^] :匹配指定范围外的任意单个字符

[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。中括号里有的都会被匹配上[a-z0-9]

字符集合:

[:digit:]数字,

[:lower:] 小写字母,

[:upper:]大写字母,

[:punct:]标点符号,

[:space:]空白,

[:alpha:]所有字母,

[:alnum:]包含所有数字的字母

[[::digit]]$ :匹配以1个数字结尾的行

[[:space:]][[::digit]]$ :匹配以1个数字,前面为空白为结尾的行

which ls|grep -v ‘^alias‘|grep -o ‘[^[:space:]]*‘   #grep去掉行首,-o:只显示被匹配到的

匹配次数:

* :匹配其前面字符任意次

.* :匹配任意长度的任意字符

\? :匹配其前面的字符1次或0次。前面需要加反斜线转义,ls |grep "pas\?"

\+ :匹配前面字符至少一次

\{m,n\}:匹配其前面的字符至少m次,至多n次。ls |grep "pas\{1,2\}"

\{m\}:匹配前面的字符m次;

\{0,n\}:匹配前面的字符至多n次;

\{1,\} :匹配其前面的字符至少1次,

位置锚定:

^ :锚定行首,此字符后面的任意内容必须出现在行首

$ :锚定行尾,此字符后面的任意内容必须出现在行尾

^PATTERN$: 用于模式匹配整行;

^$ :空行。注意:空格不等于空行

\<或\b :锚定词首,其后面的任意字符必须作为单词首部出现

\>或\b :锚定词尾,其前面的任意字符必须作为单词的尾部出现

\<root\> :表示精确匹配root这个单词,点号不算一个单词里面的字符

分组:

\(\):将一个或多个字符捆绑在一起,当作一个整体进行处理;

\(xy\)*ab

后向引用:引用前面的分组括号中的模式所匹配字符,(而非模式本身)

\1:从左侧起,第一个左括号以及与之匹配右括号之间的模式所匹配到的字符;

\(ab\+\(xy\)*\):

\1: ab\+\(xy\)*

\2: xy

grep  ‘\(l..e\).*\1‘ test.txt  ##前面出现l..e,后面调用这个单词,所以前后的一样;

He love his lover.               匹配出现相同字段的行

He like  his liker.

egrep  :扩展正则表达式,grep -E:

+ :匹配其前面的字符至少1次,不能为0次

{m,n}:也表示至少m次,至多n次,但是不要加反斜线了

():分组,也支持\1,\2,….,

a|b :或者,表示or的意思,C|cat表示匹配C或者cat,(C|c)at

IPV4:5类,A,B,C,D,E

A:1-127    B:128-191   C:192-223

2.grep命令使用简单实例

$ grep ‘test’ d*     ##后可跟多个文件名,显示所有以d开头的文件中包含 test的行。

$ grep ‘[a-z]\{5\}’ aa

显示所有包含每个字符串至少有5个连续小写字符的字符串的行。

***默认情况下,’grep’只搜索当前目录。如果 此目录下有许多子目录,’grep’会以如下形式列出:

grep: sound: Is a directory

这可能会使’grep’ 的输出难于阅读。这里有两种解决的办法:

grep -r:明确要求搜索子目录

grep -d skip:或忽略子目录

$ grep magic /usr/src/Linux/Documentation/* | less    更方便阅读

***命令行参数

grep -C number pattern files :匹配的上下文分别显示[number]行,

grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,

grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。

***这里还有些用于搜索的特殊符号:

grep ‘$‘ /etc/init.d/nfs.server | wc -l     统计一个文件共有多少行

grep ‘\<[Tt]he\>‘ size.txt   匹配单词the,t或者T都可以

grep ‘[239].‘ data.doc      #输出所有含有以2,3或9开头的,并且是两个数字的行

grep ‘^[^48]‘ data.doc      #不匹配行首是48的行

grep -E ‘219|216‘ data.doc   #使用扩展模式匹配

ps -ef|grep svn -c            查看svn这个进程的个数

grep -nf test1.txt test2.txt 匹配test1.txt中包含test2.txt内容的行,并显示行号

获取本机ip:

# ifconfig |sed -n ‘s#^.*addr:\(.*\)  Bcast.*#\1#gp‘

# ifconfig |grep "inet addr"|awk -F "[: ]+" ‘{print $4}‘     +代表重复一次或多次分隔符

# ifconfig |grep "inet addr"|cut -d ":" -f2|cut -d " " -f1

# ifconfig |awk -F "[: ]+" ‘NR==2 {print $4}‘      #用:或空格作为分隔且可重复多次

# ifconfig |sed -n ‘/inet addr/p‘|sed ‘s#^.*addr:##g‘|sed ‘s#Bcast:.*$##g‘

sed:

-n :使用安静(silent)模式。只有经过sed 特殊处理的那一行(或者动作)才会被列出来。配合p

-e :替换时前面加-e,可替换多次,仅限于替换。用;也可实现

-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;

-r :支持扩展表达式,(默认是基础正规表示法语法)

-i :直接修改读取的文件内容,而不是输出到终端。

function:

a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~

i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);

c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!

d :删除,因为是删除啊,所以 d 后面通常不接任何东东;

p :输出匹配到并改动的行。通常 p 会与参数 sed -n 一起运行~

q:退出。sed -n ‘1p;2p;5p;5q‘ files。   5q:处理到第5行退出,不往下匹配

s :替换

&:表示匹配到的内容。echo ‘12345‘|sed -r ‘s/./&\n/g‘ file    #把数字竖着打印出来

增加或插入单行内容:

sed -i ‘2a *****‘   person.txt      #在第二行增加*****内容,a是追加的意思,在之后追加

sed -i ‘2i *****‘    person.txt      #在原第二行之前插入*****内容,$为末尾,插到倒数第二行

添加多行:

sed ‘2a ****\n****‘ person.txt    #这样就可追加两行,\n换行,

sed ‘2a **** \                             #结尾为\,下面会自动显示尖括号,再输入第二行 内容

>*****‘  person.txtt

sed正则表达式用法:

10{sed-commands}                         ##对第10行操作

10,20{sed-commands}                  ##对第10到20行操作,包括10,20行

10,+20{sed-commands}               ##对第10到30(10+20)行操作,包括10,30行

1~2{sed-commands}                       ##对1,3,5,7,….行操作,等差数列

10,${sed-commands}                    ##对10到最后一行($代表最后一行)操作,包括第10行

/oldboy/{sed-commands}               ##区间操作,对匹配oldboy的行操作

/oldboy/,/Alex/{sed-commands}  ##对匹配oldboy的行到匹配Alex的行操作

/oldboy/,${sed-commands}          ##对匹配oldboy的行到最后一行操作

1,/Alex/{sed-commands}              ##对第一行到匹配Alex的行操作

d:删除指定的行,可用正则

sed ‘2d‘ person.txt                          ###指定删除第二行

sed ‘N;$d‘ file                 #删最后两行。删最后四行:cat file|sed ‘N;$d‘|sed ‘N;$d‘

cat 10|awk ‘NR==FNR{a++}NR!=FNR{if(FNR<=a-4)print $0}’ 10 10 #删除后四行

  cat 10|head -n  -4       #显示除了最后4行的全部行,-n:指定显示前多少行,

sed ‘2,5d‘ person.txt

sed ‘1d;3d‘ file                                 #删除第一行和第三行

sed ‘3,$d‘ person.txt

sed ‘/=/!d‘ person.txt                      #!:取反,删除没被匹配到的,删除不包括=号的行

sed ‘1~2d‘ person.txt                      ###删除1,3,5,7…行

sed -r ‘/^$|[ \t]+/d‘ file                   #删除空行和一个或多个空格加制位符的行,

sed ‘/zhangyao/d‘ person.txt   #匹配到zhangyao的行删掉,可用于打印不包含zhangyao的行

p:打印匹配行,-n:只显示匹配到行

sed ‘2p‘ person.txt                              ###打印两行

sed -n ‘2p‘ person.txt                         ###取消默认输出

sed -n ‘1,3p‘ person.txt                    ###打印出1-3行

sed -n ‘1~2p‘ person.txt                     ###打印出1,3,5,7…行

sed -n ‘$=‘ file                                     #显示一个文件有几行

sed -n ‘1p;3p‘  file                              ##;是中断,只显示第一和第三行,而不是1-3行

sed -n ‘/==*/p‘ file         #匹配一个或多个=的行,等同于 sed -nr ‘/=+/p‘ file

用新行取代旧行:

sed ‘2c *****‘ person.txt                     ###把第二行的内容替换成*****

文本替换:

sed -i ‘s#guopeng#xiaoying#g‘

sed -i ‘3s#guopeng#xiaoying#g‘       ###指定行进行替换

sed -i ‘98,115s/#//g‘ nginx.conf         ##去掉注释

sed -i ‘98,117s/^/#/g‘ nginx.conf       ##行首添加注释

sed -n ‘/bash/{s/bash/blueshell/;p;q}‘ /etc/passwd

如果只替换/etc/passwd的第一个bash关键字为blueshell,就退出

sed -e ‘3,$d‘ -e ‘s/bash/blueshell/‘ /etc/passwd #一条sed语句,执行多种操作

sed ‘s/^/HEAD&/g‘ test.file       ## 在每行的头添加字符,比如"HEAD"

sed ‘s/$/&TAIL/g‘ test.file          ##在每行的行尾添加字符,比如“TAIL”

sed引用外部变量:

sed "s/clone/$ip/g" file   等同于  sed ‘s/clone/‘$ip‘/g‘  #用双引或变量加双引

后向引用:

\U\1:把引用的\1内容变成大写,upper的缩写,\u:把首字母大写,\L小写

sed -r ‘s/(.*)([a-z]{3})(.*)/\3\U\2\1/g‘ file     #把\2及之后的字母都变成大写

ifconfig eth0|sed -n ‘s/^.*inet addr:\(.*\)  Bcast:.*$/\1/g‘  过滤ip

ifconfig|sed -rn ‘s/^.*inet addr:(.*) Bcast:.*$/\1/g‘p        ##不同版本sed需要加p

ifconfig eth0|sed -n ‘s/^.*inet addr:\(.*\)  Bcast:\(.*\)  Mask.*$/\1\t\2/g‘  多引用

-r  扩展正则表达式,用-r就不用加反斜线,不用转义        

# echo i am oldboy teacher.|sed ‘s#^.*am \([a-z].*\) tea.*$#\1#g‘

oldboy

# echo i am oldboy teacher.|sed -r ‘s#^.*am ([a-z].*) tea.*$#\1#g‘

oldboy

# chkconfig --list|grep  "3:启用"|grep -vE "sshd|crond|network|rsyslog|sysstat"|awk "{print $1}"|sed -r ‘s#^(.*)#chkconfig \1 off#g‘|bash

高级编辑命令:

h: 把模式空间中的内容覆盖至保持空间中;

H:把模式空间中的内容追加至保持空间中;

g: 从保持空间取出数据覆盖至模式空间;

G:从保持空间取出内容追加至模式空间;

x: 把模式空间中的内容与保持空间中的内容进行互换;

n: 读取匹配到的行的下一行至模式空间;

N:追加匹配到的行的下一行至模式空间;

d: 删除模式空间中的行;

D:删除多行模式空间中的所有行;

sed -n ‘n;p‘ FILE:显示偶数行

sed ‘n;d‘ FILE: 显示奇数行;

sed ‘1!G;h;$!d‘ FILE:逆向显示文件内容

sed -n ‘1!G;h;$p‘ FILE: 逆向显示文件中的每一行;

sed ‘$!N;$!D‘ FILE: 取出文件后两行;

sed ‘$!d‘ FILE:取出文件最后一行;

sed ‘G‘ FILE:

sed ‘/^$/d;G‘ FILE: 把多个空白行合并成一个空白行

AWK:

http://lizhenliang.blog.51cto.com/7876557/1892112?b4

-F:指明输入时用到的字段分隔符

-v var=‘value‘              ##自定义变量

-F‘[: ]+‘                         #以:号或空格一个或多个作为分隔符

-f:从文件中读取awk程序源文件,tail -n3 /etc/services |awk -f test.awk

1.print       pring $1,$2,...

1.逗号分隔符,用双引号隔起来不做变量,

2.如省略item,相当于print $0:整行意思

3.‘print $1"\t"$2‘            #指定输出分隔,"":让输出字段用什么空格

2.变量:

內建变量:

FS:定义输入文件分隔符, 默认都为空白字符

awk ‘BEGIN{FS=""}{print $1,$2}‘  file           #取消分隔符,现在每个字符作为一个字段

OFS:定义输出文件分隔符,默认都为空白字符

RS:指明输入时使用的换行符

ORS:指明输出时使用的换行符

NF:字段数,$NF:表示最后一个字段,$(NF-1)

echo "a b c d e f" |awk ‘{$NF="";$(NF-1)="";print$0}‘   排除最后两个字段:

NR:行数

awk ‘NR>1&&NR<4{print NR,$0}‘   #取出第二至第三行,并显示行号

tail -n5 /etc/services |awk ‘NR==3{print $2}‘   打印第三行第二个字段:

FNR:多文件分别统计行数,当FNR==NR时,说明在处理第一个文件内容,不等于时说明在处理

第二个文件内容。 一般FNR在处理多个文件时会用到

FILENAME:当前文件名

ARGC:命令行参数的个数

ARGV:数组,保存的是命令行所给定的各参数

   

awk -v FS=‘:‘ ‘{print $1}‘ /etc/passwd   ##-v自定义变量FS,以:作为分隔符,再取第一段

awk -F: ‘{print $1}‘ /etc/passwd   也可以用-F然后接:,效果等同于自定义变量

awk -v FS=‘:‘ -v OFS=‘:‘ ‘{print $1,$3,$7}‘ /etc/passwd   ##定义输出以什么作为分隔符,

awk ‘BEGIN{FS=":"}{print $1"#"$2}‘ /etc/passwd |head -n5   通过字符串拼接实现分隔:

awk ‘{print NF}‘ /etc/passwd 显示每行有多少个字段,不需要加$符,

awk ‘BEGIN{print ARGC}‘ /etc/fstab

awk ‘BEGIN{print ARGV[0|1|2|...]}‘ /etc/fstab

自定义变量和引用外部变量:

1.引用外部变量,需用‘BEGIN{print ‘$+变量名‘}‘  括起来,如不行,"‘ ‘" 用这种,同sed

2.-v:自定义变量或引用外部变量

awk -v a=$a ‘{print a}‘  或    awk  ‘{print ‘$a‘} ‘     #$a为引用bash变量,

awk -v test=‘hello gawk‘ ‘BEGIN{print test}‘   等同于

awk ‘BEGIN{test=‘hello gawk‘;print test}‘

3.printf  

格式化输出:printf FORMAT,item1,item2,...

FORMAT:必须要给出

不会自动换行,需要显示给出换行控制符:\n

FORMAT中需要分别为后面每个item指定一个格式化符号

格式符:

%c:显示字符的ASCII码

%d,%i:显示十进制整数

%e,%E:科学计数法数值显示

%f:显示浮点数

%g,%G:以科学计数法胡浮点形式显示数值

%s:显示字符串

%u:无符号整数

%%:显示%自身

awk -F: ‘{printf "Username:%s,UID:%d\n",$1,$3}‘ /etc/passwd   #$1赋值%s上,$3赋值在%d上

修饰符:

#[.#]:第一个数字控制显示的宽度,,第二个#表示小数点后的精度; %3.1f

-:左对齐。默认为右对齐

+:显示数值的符号

4.操作符:

算数操作符:x+y,x-y,x*y,x^y,x%y,-x,+x

字符串操作符:没有符号的操作符,字符串连接

赋值操作符:=,+=,-=,*=,/=,%=,^=,++,--

比较操作符:>,>=,<,<=,!=,==

模式匹配符:~(是否匹配),!~(是否不匹配)

awk ‘$2~/4567/{print $0}‘  #如果第二列匹配到4567,才执行后面的动作

awk ‘{if($2~/4567/){print $0}}‘   等同于上

逻辑操作符:&& , || , !

seq 6 |awk ‘i=!i‘ 打印奇数行:

seq 6 |awk ‘!(i=!i)‘ 打印偶数行:

函数调用:function_name(argu1,argu2,...)

条件表达式:selector?if-true-expression:if-false-expression

在awk中,有3种情况表达式为假:数字是0,空字符串和未定义的值

awk ‘BEGIN{n=0;if(n)print"true";else print "false"}‘       结果为:false

awk‘BEGIN{s="";if(s)print "true";else print"false"}‘        结果为:false

awk‘BEGIN{if(s)print "true";else print "false"}‘               结果为:false

seq 5 |awk ‘{print $0*2}‘                乘法

seq 5 |awk ‘{print $0%2}‘               取余

seq 5 |awk ‘$0%2==0{print $0}‘   打印偶数行:

seq 5 |awk ‘$0%2!=0{print $0}‘     打印奇数行

seq 5 |shuf |awk ‘{print$0|"sort"}‘   管道符使用

例:    

awk -F: ‘{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}‘ /etc/passwd

:作为分隔符,第三列大于等于1000就命名为Common User,小于1000的命名为Sysadmin or SysUser,%15s对应$1,%s对应usertype,\n换行,-s左对齐,%15默认为右对齐

5.模式匹配

1.empty:空模式,匹配每一行

2./regular expression/:仅处理能够被此处的模式匹配到的行

awk ‘/^UUID/{print $1}‘ /etc/fstab   centos 7的fstab文件以UUID开头。

awk ‘!/^UUID/{print $1}‘ /etc/fstab  取反

tail /etc/services |awk ‘/^blp5/{print $0}‘     匹配开头是blp5的行:

tail /etc/services |awk ‘/^[a-z0-9]{8} /{print $0}‘   匹配第一个字段是8个字符的行:

不匹配开头是#和空行:

awk‘! /^#/ && ! /^$/{print $0}‘ /etc/httpd/conf/httpd.conf

awk‘! /^#|^$/‘ /etc/httpd/conf/httpd.conf

awk‘/^[^#]|"^$"/‘ /etc/httpd/conf/httpd.conf

3.relational expression:关系表达式: 结果有“真”有“假”:结果为"真"才会被处理

真:结果为非0值,非空字符串;    

awk -F: ‘$3>=1000{print $1,$3}‘ /etc/passwd

awk -F: ‘$NF=="/bin/bash"{print $1,$NF}‘ /etc/passwd

awk -F: ‘$NF"~/bash$/"{print $1,$NF}‘ /etc/passwd

以bash$为结尾的模式匹配,模式匹配要用//括起来

4.匹配行范围:/path1/,/path2/

awk -F: ‘/^root/,/^nobody/{print $1}‘ /etc/passwd

匹配root起始的行到nobody开头的行中间的行,取第一个字段值

awk -F: ‘(NR>=2&&NR<=10){print $1}‘ /etc/passwd

5.BEGIN/END模式:

BEGIN{}:还没匹配第一行之前,先执行BEGIN的行为,用于变量赋值,输出标头

END{}:在文本处理完成之后执行END的语句,用于变量最终的输出,取最后一行

cat 10.txt|awk ‘{a+=$1}END{print a}‘    #输出1加到10的值,竖列

pa aux|awk ‘/\java/{a+=$3;b+=$4}END{print "cpu:"a" mem:"b}‘ #统计进程cpu和内存

awk -F: ‘BEGIN{print "   username    uid   \n---------------------"}{print $1,$3}END{print "==========\n     end"}‘ /etc/passwd

6.控制语句:

6.1:if-esle

语法:‘{if(condition) {statments} else {statments}}‘     双分支if语句

‘/^_/{if(***)print $0}‘     #if前面还可以接正则匹配过滤,在判断

seq 5 |awk ‘{if($0==3)print $0;else print "no"}‘

awk‘{if($1==4){print "1"} else if($2==5){print "2"} elseif($3==6){print "3"} else {print "no"}}‘ file

awk -F: ‘{if($3>=1000) print $1,$3}‘ /etc/passwd

awk -F: ‘{if($NF=="/bin/bash") print $1}‘ /etc/passwd

awk -F: ‘{if($3>=1000) {printf "Common user:%s\n",$1} else {printf "root or SysUser:%s\n",$1}}‘ /etc/passwd   centos 7是1000,centos 6是500

awk ‘{if(NF>5) print $0}‘ /etc/fstab   使用场景:对awk取得的整行或某个字段做条件判断

df -h|awk -F[%] ‘/^\/dev/{print $1}‘|awk ‘{if($NF>=20)print $1}‘   挑出dev使用率大于20的磁盘

6.2:while循环

语法:while(condition) statments

条件为“真”,进入循环,条件为“假”,退出循环

使用场景:对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用

length()  计算长度函数

awk ‘/^[[:space:]]*linux16‘/{i=1;while(i<=NF) {print $i,length($i);i++}}‘ /etc/grub2.cfg

对每一行的每一个字段做单独的统计

awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)};i++}}‘ /etc/grub2.cfg               while循环里面再嵌套if语句

break跳过所有循环,continue跳过当前循环。

awk ‘BEGIN{for(i=1;i<=5;i++){if(i==3){break};print i}}‘

awk ‘BEGIN{for(i=1;i<=5;i++){if(i==3){continue};print i}}‘

exit退出程序,与shell的exit一样。[ expr]是0-255之间的数字。

seq5 |awk ‘{if($0~/3/)exit (123)}‘

echo $?

123

6.3:do-while循环:至少执行一次循环体

6.4:for循环

语法:for (variable assignment;condition;iteration process) {for-body}

awk ‘/^[[:space:]]*linux16/{for (i=1;i<=NF;i++) {print $i,length($i)}}‘ /etc/grub2.cfg

awk ‘{for(i=1;i<=NF;i++){n++}}END{print n}‘ file  #统计文件有多少个单词,可用wc

n++:每循环一次就加1

awk ‘{for(i=1;i<=NF;i++){if($i=="60"){n++}}}END{print n}‘  file1  #统计有多少个60

df -h|awk -F‘[\t %]+‘ ‘{a=a+$5}END{print a}‘    #统计磁盘总使用率,竖列相加

特殊用法:能够遍历数组中的元素:

语法:for(var in array) {for-body}  

6.5:switch语句:

switch(expression) {case VALUE1 or /REGEXP/: statement;case VALUE2 or /REGEXP2/: statement;...;default:statement;}

6.6 next:在行间执行,提前结束

awk -F: ‘{if($3%2!=0) next; print $1,$3}‘ /etc/passwd

如果$3项除2不等于0,就直接跳到下一行处理。

7.array:数组

关联数组:array[index-expression]

index-expression:

1.可使用任意字符串,字符串要使用双引号

2.如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为"空串"

若要判断数组中是否存在某元素,要使用"index in array"格式进行

awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";print weekdays["mon"]}‘

若要遍历数组中的每个元素,要使用for循环。

注意:var会遍历array的每个索引

state["LISTEN"]++    此处LISTEN为下标

state["ESTABLISHED"]++

awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) print weekdays[i]}‘

netstat -tan|awk ‘/^tcp\>/{state[$NF]++}END{for(i in state) {print i,state[i]}}‘

awk ‘{ip[$1]++}END{for(i in ip) {print i,ip[i]}}‘ /var/log/httpd/access_log  ##计算访问ip数量

awk ‘{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}‘ /etc/fstab

##统计文件中每个文件出现的次数

去重三个方法:

awk ‘++a[$1]==1‘  file                   #同下面一行都是以最开始匹配到为基准,后面重复的忽略

awk ‘!a[$1]++‘  file                         #省略{print $0},对第4列去重就是$4

awk ‘{a[$1]=$0}END{for (i in a){print a[i]}}‘      #以最终的为基准,不断赋值,

计数:

awk ‘{a[$1]+=1}END{for(i in a){print i,a[i]}}‘   file

例1:

cat file

a 1

a 2

b 3

b 4

cat file|awk ‘{a[$1]=a[$1]+$2}END{for(i in a){print i,a[i]}}‘   #计算多个a和多个b各自的值

a 3

b 7

处理多文件:

awk ‘NR==FNR{a[FNR]=$1}NR!=FNR{print a[FNR],$2}‘ file file1

把一个文件的第一列和另一个文件的第二列拼凑起来

NR==FNR:表示处理第一个文件。

NR!=FNR:表示处理第二个文件

处理多文件计数:

awk ‘{a[$1]=a[$1]+$2}END{for(i in a){print i,a[i]}}‘ file file1 file2

二维数组行列转换:

awk ‘{for(i=1;i<=NF;i++){a[NR,i]=$i}}END{for(i=1;i<=NF;i++){for(j=1;j<=NR;j++){printf a[j,i]" "}print ""}}‘

修改第一列值:

cat file|awk ‘{$1=3}1‘ === cat file |awk ‘{$1=3;print $0}‘

两个文件行中有相同字段,合并并且以file1为准,file1需放后面:

awk ‘NR==FNR{a[$1]=$0;next}NR!=FNR{$1=a[$1];print $0}‘ file2 file1


grep、sed、awk基础