【转载更新】Linux工具之AWK 4.实例

======
基 础 篇
======

1.无pattern的action实例
  a.awk ‘{print NR $1 $NF}’data.txt           打印行号,第一列和最后一列,中间无分隔符
  b.awk ‘{print $1,$NF}’ data.txt             打印第一列和最后一列,并且中间有分隔符
  c.awk‘{print$0,$NF+10}’data.txt           打印整行,并打印 最后一行加上10的结果

2.有pattern的action实例
  a.awk ‘/[0-9]/’ data.txt                   打印记录中任意列包含数字0-9的行
  b.awk ‘/01/||/02/’ data.txt                  打印包含01或者02的行
  c.awk ‘/01/,/02/’ data.txt                打印既包含01又包含02的行;等同awk ‘/01/&&/02’
  d.awk‘$1= =1001{print $2}’ data.txt         打印符合第一列等于1001的第二列
  e.awk ‘$2==”Steven”{print}’data.txt          打印符合第二列等于Steven的那些行
  f.awk ‘$3>20&&$3<30’ data.txt              打印第三列在20到30之间的那些行
  g.nawk ‘$3*$NF<100’ data.txt              打印第三列和最后一列乘积小于100的那些行
  h.awk ‘$6~/01/{print $2}’ data.txt           打印符合仅仅第六列里包含01那些行的第二列
  i.awk‘NR>3{print $1,$2}’data.txt           从第四行才开始打印第一列和第二列

3.有BEGIN、END并包含FS、OFS的实例
  a.awk –F”+” ‘{print $1}’ data.txt                      按+为分隔符来分隔列,并打印第一列
  b.nawk–F’[+\t$]’‘{print $6,$7,$8,$9}’data.txt              按+或\t或$都可作分隔符,并打印指定列
  c.nawk‘BEGIN{FS=”[\t+$]”}{print $6,$8,$9}’data.txt           按+,\t,$(顺序无所谓)为分割符,并打印指定列
  d.nawk‘BEGIN{FS=”[\t+$]”;OFS=”%”}{print$6,$7,$8,$9}’data.txt   按+,\t,$为分割符,用%作输出分隔符打印指定列
  e.nawk –F‘[ [] ]’‘{print $1}’data.txt                   按[ 或] 为分隔符,并打印第一列
  f.nawk–F‘[][ ]’‘{print $1}’ data.txt                    同上,按[ 或] 为分隔符,并打印第一列
关于-F和BEGIN内的FS定义特别注意如下:
A.-F参数后紧跟单个分隔符,则用双引号“”,例如–F”+”
B.-F参数后紧跟多个分隔符,则用单引号‘ ’并用[ ],中间顺序无所谓,例如-F’[+$]’
C.BEGIN中的FS无论是单个还是多个分隔,均用双引号“”,多个则需加[ ]
例如:nawk‘BEGIN{FS=”[\t+$]”}{print $6,$8,$9}’data.txt
D.BEGIN中若同时有FS和OFS,则建议中间用分号“;”来分隔开,否则提示出错
例如:nawk‘BEGIN{FS=”[\t+$]”;OFS=”%”}{print$6,$7,$8,$9}’ data.txt
E.半方括号[ ]也可以作为分隔符,顺序无所谓。例如:-F‘[[]]’ 或–F‘[][]’
F.在用多个分隔符的时候,为避免语法错误或想得到正确的结果,最好用nawk

4.条件ifelse和for while循环实例
  a.nawk‘{print($3>25 ? $2“ Old” : $2“Young”)}’ data.txt      若第三列大于25就打印某某Old;否则打印某某Young
  b.awk‘{if($1>1002)print$2; else print $3}’ data.txt            若第二列大于1002就打印第二列,否则打印第三列
  c.awk‘NR>1{if($3<30)print$2;elseif($3<40) print$2”m”;else exit;}END{print10}’data.txt
    从第二行开始判断第三列的值,如果小于30就打印$2,如果大于30而又小于40,打印$2并后跟m,若是都不符合就退出处理行,但是END后的操作仍执行
  d.awk ‘BEGIN{ORS=””}{for(i=1;i<NF-2;i++) print $i”\t”}{print “\n”}’ data.txt
    打印出每行的前面几列,最后几列不打印。特别注意:默认情况下,print 每执行一次时,另起一行打印。因此为避免每打印一列就重新一行,设置ORS为空,
    但是在每打印完符合条件的所有列后,需要手工换行(循环外的print起此作用)。
  e.awk ‘BEGIN{ORS=””}{i=1;while(i<NF-2){print $i”\t”; i++}}{print “\n”}’ data.txt
    功能同上,打印出每行的前面几列,最后几列不打印。
5.数学运算和字符串操作实例
  a.nawk‘{print 2^5+sin(2.1)+int(0.9)}’ data.txt          在每一行都打印运算值(32.8632)
  b.awk‘END{print length(“How are you?”)}’ data.txt        打印出字符串的长度(12)
  c.awk ‘END{print index(“How are you?”,”you”)}’ data.txt     返回you在字符串中的开始位置(9)
  d.nawk ‘{gsub(/ \$/,””);print $0}’ data.txt            把每行的$符号用空替掉,并打印行
  e.awk‘END{print substr(“Howare you?”,9,3)}’data.txt       从字符串的第九个位置开始截出后面3个长度的子字符串
  f.nawk‘{print toupper($2), tolower($2)}’ data.txt             分别打印第二列大写和小写
  g.nawk ‘END{print match(“How are youyou?”,/you/),RSTART,RLENGTH}’data.txt
    打印you在字符串中第一个匹配的位置以及长度(9,9,3)
  h.nawk ‘END{str=”How are you doing?”;sub(/o/,”0”,str);print str}’ data.txt
    将字符串变量指定字符中第一个符合含有o的用0替换调
    特别注意:sub 函数的第三个参数不可直接用字符串,而必须用字符串变量。
  i.awk‘END{print split(“Jan,Feb,Mar,Apr,May”,mymonths,”,”),mymonths[2]}’data.txt
    将字符串用第三个参数分隔符号进行分隔,把分隔的各个元素放
    在第二个参数的数组中,函数返回分隔得到的元素数目。结果:
    (5,Feb)
=======
高 级 篇
=======
6.数组与关联数组(a[1],a[$1] a[$0],a[b[i]])
  a.awk ‘{for(i=1;i<NF;i++) {a[i]=$i;printa[i]}}’data.txt        把文件每一列按行打印
  b.awk‘{a[$1]=$2}END{for(x in a) print a[x]}’ data.txt       数组a关联到第一列,并将第二列值赋给a,最后打印a中的所有内容。
                                     注意:但不是顺序打印。for中的x是随意变量,awk自动确定。
  c.awk ‘{b[i]=$1;a[$1]=$2;i++}END{for(j=1;j<i;j++) print b[j],a[b[j]]}’ data.txt
                                    实现从第二行开始打印每一行的第一列和第二列的功能。
                                    注意:i从0开始取值,而j从1开始。a为关联数组,b为顺序数组。
7.多输入文件和NR、FNR的实例
  a. awk ‘BEGIN{OFS=FS=”:”} NR==FNR{a[$1]=$2}NR>FNR{$2=a[$1];print}’  /etc/shadow /etc/passwd
    该语句中第一个模式匹配到第一个输入文件shadow,第二个模式匹配到第二个输入文件passwd,并使用关联数组,实现不同文件关联列的其他列值相互替换。
     A.awk对多输入文件的执行顺序是,先将代码作用于第一个文件(一行行读入),然后该重复的代码又作用于第二个文件,再作用于第三个文件。
    B.awk对多输入文件的执行顺序产生了行序号的问题。当第一个文件执行完,下次读入第二个文件,那么第二个文件的第一行怎么算呢?如果又计为1的话,那不就两个1了么?(因为第一个文件也有第一行)。这就是NR和FNR的问题。
    NR :全局行数(第二个文件的第一行接着第一个文件尾行数顺序计数)
    FNR:当前文件自身的行数(不考虑前几个输入文件的自身行数及总数)
         例如:data1.txt中有40行,data2.txt中有50行,那么awk ‘{}’data1.txt data2.txt
    NR 的值依次为:1,2……40,41,42……90
    FNR的值依次为:1,2……40,1,2……50
8.重定向输出和特别函数getline实例
    a.awk ‘{print FILENAME,$0}’ data1.txt data2.txt >data_all.txt
      把第一个文件和第二个文件合并到data_all.txt 中,新文件第一列为原始文件名,后面列为原始文件内容。
    b.awk ‘$1!=fd{close(fd);fd=$1} {print substr($0,index($0,“ ”)+1)>$1}’ data_all.txt
      把合并后的新文件data.txt重新拆开成原来的两个子文件,依照新文件的第一列来产生新文件名。生成一个完整子文件后,关闭之;再生成下一个子文件。
    A.getline从整体上来说,应这么理解它的用法:
      当其左右无重定向符| 或< 时,getline作用于当前文件,读入当前文件的第一行给
      其后跟的变量var 或$0(无变量);应该注意到,由于awk在处理getline
      之前已经读入了一行,所以getline得到的返回结果是隔行的。
      当其左右有重定向符| 或< 时,getline则作用于定向输入文件,由于该文件是刚打
      开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。
    B.getline用法大致可分为三大类(每大类又分两小类),即总共有6种用法。代码如下:
      nawk ‘BEGIN{“cat data.txt”|getline d; print d}’ data2.txt
      nawk ‘BEGIN{“cat data.txt”|getline; print $0}’ data2.txt
      nawk ‘BEGIN{getline d < “data.txt”; print d}’ data2.txt
      nawk ‘BEGIN{getline < “data.txt”; print $0}’ data2.txt
      以上四行代码均实现“只打印data.txt文件的第一行”(若打印全部行,用循环)
      eg. nawk ‘BEGIN{FS=”:”;while(getline<”/etc/passwd”>0){print $1}}’ data.txt
        nawk ‘{getline d; print d”#”$3}’ data.txt
        awk首先读入第一行,接着处理getline函数,然后把下一行指定给变量d,再先打印d,由于d后面有换行符,所以后面紧跟的#会覆盖d,后面的$3同样也会覆盖d。
      nawk ‘{getline; print $0”#”$3}’ data.txt
      awk首先读入第一行接着处理getline函数,然后把下一行指定给$0,现在的$0已经是下一行内容,后面的#和$3(从$0中取)会覆盖$0的内容。
    c.nawk‘BEGIN{system(“echo \”input yourname:\””);getline var; print “\nYour name is”,d,”\n”}’
        系统提示输入名字,然后将输入的名字打印出来。特别注意:该awk语句后没有输入文件名,而是利用键盘输入作为文件名。
=========
经 典 实 例
=========

1.问题描述
有如下银行帐单部分文本,
200000000000007|shiyancityqi pei bu
202111320000018|hospital
200000000000007|shiyan cityrenmen road qibei bu
201602520002941|middle school
200000000000007|mingfeng roadqi pei
201602120000113|zhuanghuangfactory
201602320000115|liangyou factory

要求:将第一列中重复的合并为一行,其第二列填入最长地址的那列
得到的结果应为:
200000000000007|shiyan cityrenmen road qibei bu
202111320000018|hospital
201602520002941|middle school
201602120000113|zhuanghuangfactory
201602320000115|liangyou factory

代码:(假设下面代码在文件myawk..sh中)
#!/usr/bin/nawk-f
BEGIN{FS=OFS="|"; i=1;}
{ if(a[$1]==0){b[i]=$1;a[$1]=$2;i++}
if(length(a[$1])<length($2)){a[$1]=$2}
}
END{for(j=1;j<i;j++) print b[j],a[b[j]]
}
执行:myawk.sh data.txt
比较代码:(实现不全)
awk‘BEGIN{FS=OFS="|"}!(length(a[$1])>length($2)){a[$1]=$2}
END{for(i ina)print i,a[i]}‘ data.txt

解释:此例中,用了两个数组,a用来与$1关联,b用来顺序记录,使得在最后打印时是完全按照$1顺序打印。条件句首先判断数组元素是否是第一次写入,若非,则
比较当前$2值和以前储存的值长度。功能不全代码不能顺序打印。当$1有重复,而$2长度第一次、第二次、第三次是
以递减的方式时,该代码应用得较好。但是,当$2各次得到的长度不确定时,代码不能实现上述功能。例如:本例中第5行的第二列若比第3行的第二列长度长
时,功能不全代码就不能实现要求。

2.问题描述:
有两个文件如下:
data1文件内容:
1   0.5 100
10 15  36.5
data2文件内容:
50  10 19
3.2 1   5
要求:得到一个新的文件,内容是data1和data2对应的列数字相加的和,新文件内容:
51 10.5 119
13.2 16 41.5

代码:(假设下面代码在文件myawk..sh中)
#!/usr/bin/nawk-f
{ for(i=1;i<=NF;i++) a[i]=$i;
getline < “data2.txt”
for(j=1;j<NF;j++) printf $j+a[j] “\t”
printf$NF+a[NF]“\n”
}
执行:myawk.sh data1.txt
解释: 上述代码用到了getline同时读入第二个文件的行内容并存入到$0中,最后用printf来实现相加后的打印。注意后面同时紧跟打印了\t 和\n,以用来列之间的分隔和
行之间的分隔。此外,也可以用print来实现,但是print每执行完一次都要换行,(当然可以用OFS来进一步处理)。
实际上也可以用另外一种办法来实现,就是用NR、FNR比较,然后分别将两个文件赋值给不同的数组,然后相加。当然代码就没有上述代码简练。
3.问题描述
有两个如下文件:
data2.txt 文件内容如下:
01 1111 AAA WW001$$$$1000.00
02 2222BBB GG001%%%%2000.00
03 3333CCC JJ001****3000.00
04 4444DDD FF002&&&&4000.00
05 5555EEE [email protected]@@@5000.00
06 666 FFF UU003JJJJ6000.00
07 777 III II005PPPP7000.00
08 8888TTT TT008TTTT8000.00
data1.txt 文件内容如下:
AAA001 1000.00
BBB 001 2000.00
DDD 002 4000.00
EEE 002 5000.00
FFF 003 6000.00
data1的第1列、最后一列和data2的第3列、最后一列是相同的,
data1的第2列和data2的第4列的后3位是相同的。
要求:data2中第三列、第四列后3位、第六列完全和data1相同的取出来得到新文件如下内容:
01 1111AAA WW001$$$$1000.00
02 2222BBB GG001%%%%2000.00
04 4444DDD FF002&&&&4000.00
05 5555EEE [email protected]@@@5000.00
06 666 FFF UU003JJJJ6000.00
代码:
nawk‘NR<=FNR {a[$1]=$1"x"$2"x"$3}
NR>FNR { b=substr($4,3);
c=$3"x"b"x"$6;
if(c==a[$3]) print}‘data1.txt data2.txt
执行:直接执行上述代码
解释:本例巧妙地利用了组合字符串(用x来组合),然后用来比较。
当NR<=FNR时,处理第一个文件,当NR>FNR时,处理第二个文件。

【转载更新】Linux工具之AWK 4.实例

时间: 2024-10-14 07:03:54

【转载更新】Linux工具之AWK 4.实例的相关文章

【转载更新】Linux工具之AWK 3.高级知识

原文:http://blog.hexu.org/archives/41.shtml#id2874788 awk编程 14.1. 变量 在awk中,变量不需要定义就可以直接使用,变量类型可以是数字或字符串.赋值格式:Variable = expression,如$ awk ‘$1 ~/test/{count = $2 + $3; print count}’ test,上式的作用是,awk先扫描第一个域,一旦test匹配,就把第二个域的值加上第三个域的值,并把结果赋值给变量count,最后打印出来.

【转载 更新】Linux工具之AWK 2.基础知识

1. awk简介 awk是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入.一个或多个文件,或其它命令的输出.它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具.它在命令行中使用,但更多是作为脚本来使用.awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作.如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指

【转载更新】Linux工具之AWK 2.基础知识

1.awk简介awk是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入.一个或多个文件,或其它命令的输出.它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具.它在命令行中使用,但更多是作为脚本来使用.awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作.如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的

【Linux 工具--AWK】

1. awk简介 awk是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入.一个或多个文件,或其它命令的输出.它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具.它在命令行中使用,但更多是作为脚本来使用.awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作.如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指

[转载]对于Linux系统管理员很有用的16个在线工具

对于Linux系统管理员很有用的16个在线工具 08/15. 2014 1. ExplainShell.com 命令解释 对于Linux用户来说每天都会写各种命令和脚本,那么你可以使用这个网站工具来查看命令式如何工作的,这样可以避免不必要的错误出现:也是一个很好的学习命令的方式 2. BashrcGenerator.com 定制个性命令提示符 简单说就是个性化生成命令提示符,可将生成的代码写入到用户家目录的.bashrc或者可以设置全局变量文件/etc/profile对所有用户生效 可参考:ht

Linux命令行抓包及包解析工具tshark(wireshark)使用实例解析

在Linux下,当我们需要抓取网络数据包分析时,通常是使用tcpdump抓取网络raw数据包存到一个文件,然后下载到本地使用wireshark界面网络分析工具进行网络包分析. 最近才发现,原来wireshark也提供有Linux命令行工具-tshark.tshark不仅有抓包的功能,还带了解析各种协议的能力.下面我们以两个实例来介绍tshark工具.1.安装方法 CentOS: yum install -y wireshark    Ubuntu: apt-get install -y tsha

Linux工具参考篇(网摘)

Linux工具参考篇 原文出处:[Linux Tools Quick Tutorial] 1. gdb 调试利器 2. ldd 查看程序依赖库 3. lsof 一切皆文件 4. ps 进程查看器 5. pstack 跟踪进程栈 6. strace 跟踪进程中的系统调用 7. ipcs 查询进程间通信状态 8. top linux下的任务管理器 9. free 查询可用内存 10. vmstat 监视内存使用情况 11. iostat 监视I/O子系统 12. sar 找出系统瓶颈的利器 13.

【转载】linux入侵日志分析

日志也是用户应该注意的地方之一.不要低估日志文件对网络安全的重要作用,因为日志文件能够详细记录系统每天发生的各种各样的事件.用户可以通过日志文件 检查错误产生的原因,或者在受到攻击和黑客入侵时追踪攻击者的踪迹.日志的两个比较重要的作用是:审核和监测.配置好的Linux的日志非常强大.对于 Linux系统而言,所有的日志文件都在/var/log下.默认情况下,Linux的日志文件已经足够强大,但没有记录FTP的活动.用户可以通过修改 /etc/ftpacess让系统记录FTP的一切活动. Linu

linux sed,awk详解

sed命令:sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕.接着处理下一行,这样不断重复,直到文件末尾.文件内容并没有 改变,除非你使用重定向存储输出.Sed主要用来自动编辑一个或多个文件:简化对文件的反复操作:编写转换程序等.sed使用参数[[email protected] ~]# sed [-nefr] [动作]-n :使