使用awk格式化输出文本

注意:本文并不是一篇awk入门文章,而是偏重实例讲解,由于awk是借鉴了c语法,因此awk的许多地方还保留有c语言的痕迹,比如printf语句;for,if的语法结构等

介绍

最简单地说,AWK 是一种用于处理文本的编程语言工具,处理模式是只要在输入数据中有模式匹配,就执行一系列指令。awk命令格式为:

awk {pattern + action} {filenames}

awk可以读取后接的文件,也可以读取来自前一命令的标准输入,它分别扫描输入数据的每一行,查找命令行中pattern是否匹配。如果匹配,则进行后续动作action。如果pattern不匹配或action部分处理完毕,则继续处理下一行,直到结束

相比于sed常常作用于一整行的处理,awk则比较倾向于将一行分成数个字段来处理。awk将输入数据视为一个文本数据库,像数据库一样,它也有记录和字段的概念。默认情况下,记录的分隔符是回车,字段的分隔符是空白符(空格,\t),所以输入数据的每一行表示一个记录,而每一行中的内容被空白分隔成多个字段。利用字段和记录,awk可以非常灵活地处理文件

语法

1 语法

一个典型的awk语法如下:

awk ‘{ 

     BEGIN{stat1}
     BEGIN{stat2}
     pattern1{action1}
     pattern2{action2}
     ...
     patternn{actionn}
     {默认动作,无条件,始终执行} 

     END{stat1}
     END{stat2}
}‘ 

其中BEGIN为处理文本前的操作,一般用于改变FS,OFS,RS,ORS等,BEGIN部分完成之后,awk读取第一行输入,并将第一行的数据填入$0,$1,$2,NR,NF等变量,然后进入正式处理阶段,待所有行处理完毕之后,进入END部分,END一般用于总结,打印报表等。正式处理是一个内建的循环,每一次循环读取一行数据,每一行的处理分为多模式,多动作,文本行符合条件pattern1就执行动作action1符合pattern2就执行动作action2…,还可以有默认的动作, 即没有pattern判断,始终执行此{}内的action。

BEGIN,END部分不是必须出现,可以没有,也可以有任意多个

pattern部分的写法有:

  • /reg/: 在整行范围内匹配reg,匹配到就执行后续动作
  • ! /reg/: 整行没匹配到reg,才执行后续动作
  • $1 ~ /reg/:只在第一字段匹配reg
  • $1 !~ /reg/: 不匹配
  • NR>=2: 从第二行开始处理

pattern,部分和随后的if,for部分,能用到的符号有:

2 内建变量

$0
当前记录(这个变量中存放着整个行的内容)
$1~$n
当前记录的第n个字段,字段间由FS分隔
FS
输入字段分隔符 默认是空格或\t
NF
当前记录中的字段个数,就是有多少列
NR
已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR
当前记录数,与NR不同的是,这个值会是各个文件自己的行号
RS
输入的记录分隔符, 默认为换行符
OFS
输出字段分隔符, 默认也是空格
ORS
输出的记录分隔符,默认为换行符
FILENAME
当前输入文件的名字

3 if,for语句

#在任何时候{}内都可以跟多个并列动作(使用“;”分隔),下面的{action1} 和 {action1;action2;...} 都表示{}体内有多个动作,两种表示没有任何区别,写第二种仅仅是为了直观的表示可以有多个动作

#for循环写法

for(i=1;i<=NF;i++){action1; action2; ..} #{}中用分号分隔多个动作
for(i=1;i<=NF;i++)if; else if;else #for后接一个if结构
for(i=1;i<=NF;i++)printf “for add” #简单的循环打印

#if 判断写法

if($1 ~ /reg/){action1}; else if($1 ~ /reg2/){action2}; else{action3} #else if部分可以没有
if($1 ~ /reg/ && $2 ~ /reg2/){action} #多个条件用”&&”,”||”表示
if($1 ~ /reg/ || NR >= 5){action

# if,for 混合写法

{ for(i=1;i<=NF;i++)if(…) printf “test”; else if(…) printf “test2”; else printf “test3”; print "not_for" } #print “not_for”部分是并列与for循环结构的另一个action,在for循环之外,只会打印一次
{ for(i=1;i<=NF;i++){if(…) printf “test”; else if(…) printf “test2”; else printf “test3”;print “in_for“}; print "not_in_for" }
{ for(i=1;i<=NF;i++){if {s1;s2;} else if {s3;s4;} else {s5;s6;}; print "test"} }  #else if前不加分号
{ for(i=1;i<=NF;i++)printf "for_add"; if(…);else if(…); else } #if并不在for循环体内

for循环的作用范围为:

  • 其后紧跟的if; else if; else语句
  • 其后紧跟的{}中的多个动作
  • 其后紧跟的一个第一个普通动作

if语句的作用范围:

  • if后紧跟的第一个动作
  • if后紧跟的{}中的多个动作

4 awk技巧

1: AWK使用的RE为ERE

2: 如果在BEGIN中设置了OFS, 只有$0有改动OFS才能生效

3: printf 与 print 的区别: printf 不自动打印换行符, print 则自动打印

4: gsub的返回值并不是替换后的字符串,而是返回替换的次数

5: 字符串常量一定在用" "包围起来,否则当作变量使用, 如 $1=="ipaddress"

6: AWK 的 for 循环为 C-Style,即为 for(), 区别于shell中的for i in ...

7: AWK中可以使用多个分隔符,要封装在方括号里,用‘ ‘包围,以防 shell 对它们进行解释,如 awk -F ‘[ :/t]‘ ,使用空格,冒号,tab作为分隔符

8: next语句:从输入文件中取得下一个输入行,在AWK命令表顶部重新执行命令,一般用于跳过一些特殊的行

9: awk 匹配多个条件: awk ‘/kobe/ && /james/‘ #匹配同时有kobe和james的行

10: FS的默认值是[ /t/n]+, OFS的默认值为空格,RS,ORS的默认值都是换行

11: 定位行有两种方法: 1: NR==行号 2: 用RE /Love$/

12: exit语句:终止AWK程序,但不跳过END语句

13:$1..$n表示第几列(字段),$0表示整个行.

14:awk可用比较运算符:!=, >, <, >=, <=

15:"awk ‘$6 ~ /FIN/{print $6}‘" ~ 表示模式开始,/reg/中是正则表达式匹配模式

16: 字符串匹配:~: 匹配 !~: 不匹配

17: &&:多个条件且, || 多个条件或

18: {s1;s2;s3;...}中多个语句用分号隔开;if; else if; else

awk 实例

awk ‘/AL/ {printf $1; print $2}‘ emp.txt
awk ‘/AL/{print $1} {print $2}‘ emp.txt

#第一种只处理匹配到AL的行; 然后打印这些行的第一字段和第二字段

#第二种只有在匹配到AL的行才打印字段一,但是字段二是无条件的,始终打印

时间: 2024-10-06 01:14:35

使用awk格式化输出文本的相关文章

格式化输出文本的方法

1 #!/usr/bin/env python 2 #_*_ coding:utf-8 _*_ 3 #输出代码的头部信息的三种方法 4 5 str1 = 'version' 6 num = 1.0 7 time = '2016-9-25' 8 auther = 'lys' 9 qq = '1234567' 10 addr = '北京天通苑301' 11 12 #%10s是前面除了字符,不够10个了用后面的+填充 格式化输出用元祖的方式 13 #print (('%10s%5s' %(str1,n

awk内置字符串函数 awk 格式化输出

printf -                                      左对齐 Width                                  域的步长,用0表示0步长 .prec                                  最大字符串长度,或小数点右面的位数 %c                                     ASCII字符 %d                                     整型 %e

使用shell+awk完成Hive查询结果格式化输出

好久不写,一方面是工作原因,有些东西没发直接发,另外的也是习惯给丢了,内因所致.今天是个好日子,走起! btw,实际上这种格式化输出应该不只限于某一种需求,差不多是通用的. 需求: --基本的:当前Hive查询结果存在数据与表头无法对其的情况,不便于监控人员直接查看,或者导出到excel中,需要提供一个脚本,将查询结果处理下,便于后续的查看或者操作. --额外的:A.每次查询出来的结果字段数.字段长度不固定:B.每个数据文件中可能包含不只一套查询结果,即存在多个schema. 想法: 对于基本需

格式化输出命令printf

格式化输出:printf 在linux的命令行下,如果我们要对数据进行格式化输出的话,要怎样实现呢?  使用vim或nano这些文本编辑器嘛?不,我们可以使用printf这个格式化输出命令. printf语法 printf   打印格式   实际内容         格式符: %c: 显示字符的ASCII码: %d, %i: 显示十进制整数: %e, %E: 科学计数法数值显示: %f:显示为浮点数: %g, %G:以科学计数法或浮点形式显示数值: %s:显示字符串: %u:无符号整数: %%:

AWK增强的文本处理shell特征--AWK完全手册

AWK这是一个很好的文字处理工具. 它不仅 Linux 中也是不论什么环境中现有的功能最强大的数据处理引擎之中的一个. 本文主要摘录池中龙写的Unixawk使用手冊(第二版),对当中内容略微修改.感谢作者的分享. 目 录 1 0作者的话 2 1awk的调用方式 3 2awk的语法 4 3awk的记录.字段与内置变量 5 4awk的内置函数 5 5在命令行使用awk 6 6awk的变量 7 7运算与推断 7 8awk的流程控制 8 8.1BEGIN和END: 8 8.2流程控制语句 9 8.2.1

Linux常用基本命令:三剑客命令之-awk格式化动作

我们之前说过,awk是一个超强的文本格式化工具,而本文的printf动作就是经常用来做格式化文本的.使用方式跟c语言的printf差不多. 1,printf默认不会回车换行 [email protected]:~/linux/awk$ awk 'BEGIN{print "abc"}' abc [email protected]:~/linux/awk$ awk 'BEGIN{printf "abc"}' [email protected]:~/linux/awk$

String.Format数字格式化输出 {0:N2} {0:D2} {0:C2} (转)

String.Format数字格式化输出 {0:N2} {0:D2} {0:C2} (转) //格式为sring输出 // Label1.Text = string.Format("asdfadsf{0}adsfasdf",a); // Label2.Text = "asdfadsf"+a.ToString()+"adsfasdf"; // Label1.Text = string.Format("asdfadsf{0:C}adsfas

fortran之format格式化输出总结

先贴一段别人总结好的: 格式化输出的控制字符非常的丰富,但常用的并不多,一般说来:" I .F.E.A.X "是最常使用的几个格式,最 好把它们都记下来. Iw[.m] 以w个字符的宽度来输出整数,至少输出m个数字. 如:write(*,"(I5)") 100   输出:_ _100 ; 前面两空格 Fw.d 以w个字符文本框来输出浮点数,小数部分占d个字符宽,输出文本框的设置不中会出现*号. 如:write(*,"(F9.3)") 123.45

【Python④】python恼人的字符串,格式化输出

恼人的字符串 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.由于计算机是美国人发明的,因此,最早只有127个字母被编码到计算机里,也就是大小写英文字母.数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母a的编码是97. 但是要处理中文至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去.全世界有上百种语言,为了扩充ASCII编码,用于显示本国的语言,不同的国家和地区制定了不同的标准,由此产生