相较于sed 常常作用于一整个行的处理,awk 则比较倾向于一行当中分成数个『字段』来处理。 因此,awk 相当的适合处理小型的数据数据处理呢!

awk 通常运作的模式是这样的:

[root@linux ~]# awk '条件类型 1{动作 1} 条件类型 2{动作 2} ...' filename

awk 可以处理后续接的档案,也可以读取来自前个指令的standard output 。 但如前面说的,awk 主要是处理『每一行的字段内的数据』,而预设的『字段的分隔符为"空格键" 或"[tab]键" 』!

每一行的每个字段都是有变量名称的,那就是$1, $2... 等变量名称,$0 代表『一整列资料』的意思。

整个awk 的处理流程是:

1.  读入第一行,并将第一行的资料填入 $0, $1, $2.... 等变数当中;

2.  依据"条件类型" 的限制,判断是否需要进行后面的"动作";

3.  做完所有的动作与条件类型;

4.  若还有后续的『行』的数据,则重复上面1~3 的步骤,直到所有的数据都读完为止。

变量名称  代表意义

NF        每一行($0) 拥有的字段总数

NR        目前awk 所处理的是『第几行』数据

FS         目前的分隔字符,预设是空格键

如 [root@linux ~]# last | awk '{print $1 "\t lines: " NR "\t columes: " NF}'

awk的一般语法格式为:

awk [-参数 变量] 'BEGIN{初始化}条件类型1{动作1}条件类型2{动作2}。。。。END{后处理}'

其中:BEGIN和END中的语句分别在开始读取文件(in_file)之前和读取完文件之后发挥作用,可以理解为初始化和扫尾。

(1)参数说明:

-F re:允许awk更改其字段分隔符

-v var=$v 把v值赋值给var,如果有多个变量要赋值,那么就写多个-v,每个变量赋值对应一个-v

e.g. 要打印文件a的第num行到num+num1行之间的行,

awk -v num=$num -v num1=$num1 'NR==num,NR==num+num1{print}' a

-f progfile:允许awk调用并执行progfile程序文件,当然progfile必须是一个符合awk语法的程序文件。

(2)awk内置变量:

ARGC    命令行参数的个数

ARGV    命令行参数数组

ARGIND 当前被处理文件的ARGV标志符

e.g 有两个文件a 和b

awk '{if(ARGIND==1){print "处理a文件"} if(ARGIND==2){print "处理b文件"}}' a b

文件处理的顺序是先扫描完a文件,再扫描b文件

NR   已经读出的记录数

FNR    当前文件的记录数

上面的例子也可以写成这样:

awk 'NR==FNR{print "处理文件a"} NR > FNR{print "处理文件b"}' a b

输入文件a和b,由于先扫描a,所以扫描a的时候必然有NR==FNR,然后扫描b的时候,FNR从1开始计数,而NR则接着a的行数继续计数,所以NR > FNR

e.g 要显示文件的第10行至第15行

awk 'NR==10,NR==15{print}' a

FS   输入字段分隔符(缺省为:space:),相当于-F选项

awk -F ':' '{print}' a    和   awk 'BEGIN{FS=":"}{print}' a 是一样的

OFS输出字段分隔符(缺省为:space:)

awk -F ':' 'BEGIN{OFS=";"}{print $1,$2,$3}' b

如果cat b为

1:2:3

4:5:6

那么把OFS设置成";"后就会输出

1;2;3

4;5;6

(小注释:awk把分割后的第1、2、3个字段用$1,$2,$3...表示,$0表示整个记录(一般就是一整行))

NF:当前记录中的字段个数

awk -F ':' '{print NF}' b的输出为

3

3

表明b的每一行用分隔符":"分割后都3个字段

可以用NF来控制输出符合要求的字段数的行,这样可以处理掉一些异常的行

awk -F ':' '{if (NF == 3)print}' b

RS:输入记录分隔符,缺省为"\n"

缺省情况下,awk把一行看作一个记录;如果设置了RS,那么awk按照RS来分割记录

例如,如果文件c,cat c为

hello world; I want to go swimming tomorrow;hiahia

运行 awk 'BEGIN{ RS = ";" } {print}' c 的结果为

hello world

I want to go swimming tomorrow

hiahia

合理的使用RS和FS可以使得awk处理更多模式的文档,例如可以一次处理多行,例如文档d cat d的输出为

1 2

3 4 5

6 7

8 9 10

11 12

hello

每个记录使用空行分割,每个字段使用换行符分割,这样的awk也很好写

awk 'BEGIN{ FS = "\n"; RS = ""} {print NF}' d 输出

2

3

1

ORS:输出记录分隔符,缺省为换行符,控制每个print语句后的输出符号

awk 'BEGIN{ FS = "\n"; RS = ""; ORS = ";"} {print NF}' d 输出

2;3;1

(3)awk读取shell中的变量

可以使用-v选项实现功能

$b=1

$cat f

apple

$awk -v var=$b '{print var, $var}' f

1 apple

至于有没有办法把awk中的变量传给shell呢,这个问题我是这样理解的。shell调用awk实际上是fork一个子进程出来,而子进程是无法向父进程传递变量的,除非用重定向(包括管道)

a=$(awk '{print $b, '$b'}' f)

$echo $a

apple 1

(4)输出重定向

awk的输出重定向类似于shell的重定向。重定向的目标文件名必须用双引号引用起来。

$awk '$4 >=70 {print $1,$2 > "destfile" }' filename

$awk '$4 >=70 {print $1,$2 >> "destfile" }' filename

(5)awk中调用shell命令:

1)使用管道

awk中的管道概念和shell的管道类似,都是使用"|"符号。如果在awk程序中打开了管道,必须先关闭该管道才能打开另一个管道。也就是说一次只能打开一个管道。shell命令必须被双引号引用起来。“如果打算再次在awk程序中使用某个文件或管道进行读写,则可能要先关闭程序,因为其中的管道会保持打开状态直至脚本运行结束。注意,管道一旦被打开,就会保持打开状态直至awk退出。因此END块中的语句也会收到管道的影响。(可以在END的第一行关闭管道)”

awk中使用管道有两种语法,分别是:

awk output | shell input

shell output | awk input

对于awk output | shell input来说,shell接收awk的输出,并进行处理。需要注意的是,awk的output是先缓存在pipe中,等输出完毕后再调用shell命令 处理,shell命令只处理一次,而且处理的时机是“awk程序结束时,或者管道关闭时(需要显式的关闭管道)”

$awk '/west/{count++} {printf "%s %s\t\t%-15s\n", $3,$4,$1 | "sort +1"} END{close "sort +1"; printf "The number of sales pers in the western"; printf "region is " count "." }' datafile (解释:/west/{count++}表示与“wes”t进行匹配,若匹配,则count自增)

printf函数用于将输出格式化并发送给管道。所有输出集齐后,被一同发送给sort命令。必须用与打开时完全相同的命令来关闭管道(sort +1),否则END块中的语句将与前面的输出一起被排序。此处的sort命令只执行一次。

在shell output | awk input中awk的input只能是getline函数。shell执行的结果缓存于pipe中,再传送给awk处理,如果有多行数据,awk的getline命令可能调用多次。

$awk 'BEGIN{ while(("ls" | getline d) > 0) print d}' f

  1. #!/bin/shZZ
  2.  
  3. export LANG=C;
  4. export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK;
  5.  
  6. time1=`date +%Y%m%d`
  7.  
  8. #if [ $# != 1 ] ; then
  9. # echo 'Usage '
  10. # echo $ ':<filename>'
  11. # exit -
  12. #fi
  13.  
  14. #cat $ | while read LINE
  15. #do
  16.  
  17. #MERCHANTID=`echo $LINE|awk -F ":" '{ print $1 }'`
  18. #PREBRANCHID=`echo $LINE|awk -F ":" '{ print $2 }'`
  19.  
  20. #echo "MERCHANTID:$MERCHANTID"
  21. #echo "PREBRANCHID:$PREBRANCHID"
  22.  
  23. sqlplus -S abcabc/@server<<EOF
  24. WHENEVER OSERROR exit failure rollback;
  25. WHENEVER SQLERROR exit failure rollback;
  26.  
  27. delete from myjnls;
  28.  
  29. insert into myjnls select servcode,tradecode,localdate,localtime,localno,localmtdate from jnls where localdate='';
  30.  
  31. EOF
  32.  
  33. #done

linux之awk的更多相关文章

  1. linux中awk的使用

    在linux中awk绝对是核心工具,特别是在查找搜索这一领域,和掌握sed命令一样重要 下面为awk的一些基本知识,基于这些知识,可以让你随意操控一个文件: 在awk中:()括号为条件块,{}为执行的 ...

  2. linux 的 awk 使用

    linux中awk命令对文本内容进行操作,其功能十分强大 1.如:查看一个有几百万行内容的文件中第3列数字内容(不重复) cat test.csv | awk -F ',' '{print $3}' ...

  3. Linux中awk后面的RS, ORS, FS, OFS 用法

    Linux中awk后面的RS, ORS, FS, OFS 含义 一.RS 与 ORS 差在哪   我们经常会说,awk是基于行列操作文本的,但如何定义“行”呢?这就是RS的作用.  默认情况下,RS的 ...

  4. 【转】如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等

    如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等   你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作——一些无法并 ...

  5. [转帖]Linux中awk工具的使用

    Linux中awk工具的使用 2018年10月09日 17:26:20 谢公子 阅读数 2170更多 分类专栏: linux系统安全   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权 ...

  6. 性能工具之linux三剑客awk、grep、sed详解

    前言 linux 有很多工具可以做文本处理,例如:sort, cut, split, join, paste, comm, uniq, column, rev, tac, tr, nl, pr, he ...

  7. linux中awk命令(最全面秒懂)

    目录 一:linux中awk命令 1.awk命令简介 2.awk作用 3.awk的语法格式 4.解析awk使用方法 5.参数 6.awk的生命周期 二:awk中的预定义变量 三:awk运行处理规则的执 ...

  8. linux中awk命令详解(最全面秒懂)

    一:linux中awk命令 1.awk命令简介 AWK 是一种处理文本文件的语言,是一个强大的文本分析工具. 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinber ...

  9. Linux三剑客awk

    Linux三剑客awk awk是一个强大的linux命令,有强大的文本格式化的能力,好比将一些文本数据格式化成专业的excel表的样式 awk早期在Unix上实现,我们用的awk是gawk,是GUN ...

随机推荐

  1. Java提高学习之Object(4)

    哈希码 问: hashCode()方法是用来做什么的? 答: hashCode()方法返回给调用者此对象的哈希码(其值由一个hash函数计算得来).这个方法通常用在基于hash的集合类中,像java. ...

  2. 使用fastcgi_cache加速网站

    为了提高网站的性能缓存是一把利器,nginx中可以配置fastcig_cache来缓存不需要实时获取的数据实现动静分离,nginx.conf配置如下: http {     -     fastcgi ...

  3. 用不动点组合子解递归(python实现)

    不动点组合子 Y = λf. (λx. f (x x)) (λx. f (x x)) θ = (λx. λy. (y(x x y))) (λx.λy.(y(x x y))) Y f = f (Y f) ...

  4. 深入Android媒体存储服务(一):APP与媒体存储服务的交互

    简介: 本文介绍如何在 Android 中,开发者的 APP 如何使用媒体存储服务(包含MediaScanner.MediaProvider以及媒体信息解析等部分),包括如何把 APP 新增或修改的文 ...

  5. libcurl get post http

    一.              概念 1.         为什么要使用libcurl 1)        作为http的客户端,可以直接用socket连接服务器,然后对到的数据进行http解析,但要 ...

  6. paip.c++ qt 项目工程互相引用的方法

    paip.c++ qt 项目工程互相引用的方法 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn.net/ ...

  7. 【G-BLASTN 1.0正式发布】

    [G-BLASTN 1.0正式发布]G-BLASTN使用GPU来加速NCBI-BLAST里的BLASTN模块,单块GTX780比四核CPU平均快6倍. http://www.comp.hkbu.edu ...

  8. Python文件或目录操作的常用函数

    ◆ os.listdir(path) Return a list containing the names of the entries in the directory given by path. ...

  9. 游戏开场镜头拉近(Unity3D开发之四)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/? p=553 今天看了个Demo.发现 ...

  10. C语言的复合文字

    假设需要向一个带有int型参量的函数传递一个值,这时可以传递一个int型常量,也可以传递一个int型的变量.在C99标准之前,数组参数情况于现在不一样,没有所谓的数组常量可供传递,而在C99中增加了复 ...