相较于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

 #!/bin/shZZ

 export LANG=C;
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK; time1=`date +%Y%m%d` #if [ $# != 1 ] ; then
# echo 'Usage '
# echo $ ':<filename>'
# exit -
#fi #cat $ | while read LINE
#do #MERCHANTID=`echo $LINE|awk -F ":" '{ print $1 }'`
#PREBRANCHID=`echo $LINE|awk -F ":" '{ print $2 }'` #echo "MERCHANTID:$MERCHANTID"
#echo "PREBRANCHID:$PREBRANCHID" sqlplus -S abcabc/@server<<EOF
WHENEVER OSERROR exit failure rollback;
WHENEVER SQLERROR exit failure rollback; delete from myjnls; insert into myjnls select servcode,tradecode,localdate,localtime,localno,localmtdate from jnls where localdate=''; EOF #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. utf8+bom格式保存php curl乱码问题

    今天开发遇到一个php curl取数据乱码问题 不是gzip也不是编码设置问题 最后有一同事判断为utf8+bom保存数据原因,懒得深入了解utf8+bom,仅做记录 [root@centos5 ~] ...

  2. su 切换用户

    大部分Linux发行版的默认账户是普通账户,而更改系统文件或者执行某些命令,需要root身份才能进行,这就需要从当前用户切换到root用户,Linux中切换用户的命令是su或su - 前者只是切换ro ...

  3. 【iOS技术】Xcode+GitHub远程代码托管(GIT, SVN)

    原创 2016-05-24 旭哥 蓝鸥 学生对旭哥的评价是这样的: 旭哥 为什么这么年轻 知识却比我们多这么多............ 旭哥很是负责,对同学的各种问题都能够热心地解答,在旭哥的带领下, ...

  4. CFILE追加写入文件

    CFile file; file.Open(strName, CFile::modeWrite|CFile::modeNoTruncate|CFile::modeCreate); ) { file.S ...

  5. js 全局变量

    使用cookies可以设置全局变量 ,由于每次刷新变量都会为初始值,cookies可以作为全局变量的容器

  6. 从零开始PHP学习 - 第一天

    写这个系列文章主要是为了督促自己  每天定时 定量消化一些知识! 同时也为了让需要的人 学到点啥~! 本人技术实在不高!本文中可能会有错误!希望大家发现后能提醒一下我和大家! 偷偷说下 本教程最后的目 ...

  7. 一个基于MINA框架应用的最简单例子

    直接上代码.关于原理和主要的API以后在说.先能跑通了在说. 主要的包:mina-core-2.0.0.jar[到官网上下载完整项目包里面还有文档和依赖包],jcl-over-slf4j-1.5.11 ...

  8. C# 多线程使用队列注意事项

    问题: 多线程运行时死亡机问题很频繁! 推理: 看源码推理,发现 Queue<T>这样的泛型不是线程安全的. 验证: 将 Queue<T> 换成 Queue 类,并以 lock ...

  9. [LeetCode][Python]Longest Palindromic Substring

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com'https://oj.leetcode.com/problems/longest ...

  10. rsyslog 配置

    在Debian环境下: 1,配置文件在/etc/rsyslogd.conf下: 2,如果要增加配置,并且不想直接修改rsyslogd.conf文件,可以在/etc/rsyslog.d/目录下增加文件, ...