Linux如何使用文本处理工具awk

2016-02-19 13:37 10 1 收藏

下面图老师小编要跟大家分享Linux如何使用文本处理工具awk,简单的过程中其实暗藏玄机,还是要细心学习,喜欢还请记得收藏哦!

【 tulaoshi.com - Linux教程 】

awk是Linux中的文本处理工具,类似于shell编程语言,拥有属于自己的语言,下面图老师小编就给大家介绍下Linux中awk文本处理工具的用法,感兴趣的朋友可以来了解一下。

 Linux如何使用文本处理工具awk

调用方式

1.命令行

awk [-F field-separator] ‘commands’ input-file(s)

commands是真正awk命令,[-F域分隔符]是可选的。input-file(s) 是待处理的文件。在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格(或者tab)。

2.shell脚本方式

将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用。相当于shell脚本首行的:#!/bin/sh 可以换成:#!/bin/awk -f

3.将所有的awk命令插入一个单独文件,然后调用:awk -f awk-script-file input-file(s)其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

内置变量

ARGC:命令行参数个数

ARGV:命令行参数排列

ENVIRON:UNIX环境变量

ERRNO:UNIX系统错误消息

FILENAME:awk浏览的文件名

OFMT:数字的输出格式 %.6g

FNR:浏览文件的记录数

FS:设置输入域分隔符,等价于命令行 -F选项

NF:浏览记录的域的个数

NR:已读的记录数,就是行号,从1开始

FNR:当前记录数

OFS:输出域分隔符

ORS:输出记录分隔符

RS:控制记录分隔符

$0:当前记录(作为单个变量)

$1~$n:当前记录的第n个字段,字段间由FS分隔

输出函数

print:参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已

printf:其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。具体格式如下:

%d 十进制有符号整数

%u 十进制无符号整数

%f 浮点数

%s 字符串

%c 单个字符

%p 指针的值

%e 指数形式的浮点数

%x %X 无符号以十六进制表示的整数

%o 无符号以八进制表示的整数

%g 自动选择合适的表示法

获取外部变量

1.获取普通外部变量

awk ‘{action}’ 变量名=变量值

2.BEGIN程序块中变量

awk –v 变量名=变量值 [–v 变量2=值2 ] ‘BEGIN{action}’

3.环境变量

需要用到内置变量ENVIRON实现

运算符

1.赋值运算符

= += -= *= /= %= ^= **=

2.逻辑运算符

||:逻辑或

&&:逻辑与

3.正则运算符

~:匹配正则表达式

~!:不匹配正则表达式

4.关系运算符

《 《= 》 》= != ==

5.算术运算符

+ - * / & ++ --

6.其它运算符

$:字段引用

空格:字符串连接符

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

?:C条件表达式

in:数组中是否存在某键值

字符操作

1.字符串转数字

将变量通过+连接运算。自动强制将字符串转为整型。非数字变成0,发现第一个非数字字符,后面自动忽略

2.数字转字符串

只需要将变量与符号连接起来运算即可

3.字符串连接

只需要将变量与符号连接起来运算即可

数组操作

在awk中数组叫做关联数组,因为下标既可以是数也可以是串。awk中的数组不必提前声明,也不必声明大小。数组元素用0或空串来初始化,这根据上下文而定。需要注意的是不同版本下面函数不一定相同。其相关的函数有length、asort、delete、split。当然也可以实现多维数组。

流程控制语句

1.条件判断语句(if)

if(表达式){语句1}else{语句2}

if(表达式){语句1}else if(表达式){语句2}else{语句3}

2.循环语句(while、for、do while)

while(表达式){语句}

for(变量 in 数组){语句}

for(变量;条件;表达式){语句}

do{语句}while(条件)

3.关键字

break:当break语句用于while或for语句时,导致退出程序循环。

continue:当continue语句用于while或for语句时,使程序循环移动到下一个迭代。

next:能能够导致读入下一个输入行,并返回到脚本的顶部。这可以避免对当前输入行执行其他的操作过程。

exit:语句使主输入循环退出并将控制转移到END,如果END存在的话。如果没有定义END规则,或在END中应用exit语句,则终止脚本的执行。

正则表达式

+:包含一个或多个字符或扩展正则表达式的具体值(在 +(加号)前)在这个字符串中,则字符串匹配。命令行:awk ’/smith+ern/‘ testfile

?:包含零个或一个字符或扩展正则表达式的具体值(在 ?(问号)之前)在字符串中,则字符串匹配。命令行:awk ’/smith?/‘ testfile

|:以 |(垂直线)隔开的字符串的任何一个在字符串中,则字符串匹配。命令行:awk ’/allen | alan /‘ testfile

():在正则表达式中将字符串组合在一起。命令行:awk ’/a(ll)?/‘ testfile

{m}:有m个模式的具体值位于字符串中,则字符串匹配。命令行:awk ’/l{2}/‘ testfile

{m,}:至少m个模式的具体值在字符串中,则字符串匹配。命令行:awk ’/t{2,}/‘ testfile

{m, n}:在m和n之间(包含的m和n)个模式的具体值在字符串中(其中m 《= n),则字符串匹配。命令行:awk ’/er{1, 2}/‘ testfile

[String]:正则表达式与方括号内String变量指定的任何字符匹配。命令行:awk ’/sm[a-h]/‘ testfile

[^ String]:在 [ ](方括号)和在指定字符串开头的 ^ (插入记号) 指明正则表达式与方括号内的任何字符不匹配。这样,命令行:awk ’/sm[^a-h]/‘ testfile

~,!~:表示指定变量与正则表达式匹配或不匹配的条件语句。命令行:awk ’$1 ~ /n/‘ testfile

^:指定字段或记录的开头。命令行:awk ’$2 ~ /^h/‘ testfile

$:指定字段或记录的末尾。命令行:awk ’$2 ~ /y$/‘ testfile

。:表示除了在空白末尾的终端换行字符以外的任何一个字符。命令行:awk ’/a..e/‘ testfile

:转义字符。当位于在扩展正则表达式中具有特殊含义的任何字符之前时,转义字符除去该字符的任何特殊含义。例如,命令行:/a///

内置函数

1.算术函数

atan2( y, x ) 返回 y/x 的反正切。

cos( x ) 返回 x 的余弦;x 是弧度。

sin( x ) 返回 x 的正弦;x 是弧度。

exp( x ) 返回 x 幂函数。

log( x ) 返回 x 的自然对数。

sqrt( x ) 返回 x 平方根。

int( x ) 返回 x 的截断至整数的值。

rand( ) 返回任意数字 n,其中 0 《= n 《 1。

srand( [Expr] ) 将 rand 函数的种子值设置为 Expr 参数的值,或如果省略 Expr 参数则使用某天的时间。返回先前的种子值。

2.字符串函数

gsub( Ere, Repl, [ In ] ) 除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行,。

sub( Ere, Repl, [ In ] ) 用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。

index( String1, String2 ) 在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。

length [(String)] 返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。

blength [(String)] 返回 String 参数指定的字符串的长度(以字节为单位)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。

substr( String, M, [ N ] ) 返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。如果未指定 N 参数,则子串的长度将是 M 参数指定的位置到 String 参数的末尾 的长度。

match( String, Ere ) 在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。

split( String, A, [Ere] ) 将 String 参数指定的参数分割为数组元素 A[1], A[2], 。 。 。, A[n],并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数组中的元素用字符串值来创建。

tolower( String ) 返回 String 参数指定的字符串,字符串中每个大写字符将更改为小写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。

toupper( String ) 返回 String 参数指定的字符串,字符串中每个小写字符将更改为大写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。

sprintf(Format, Expr, Expr, 。 。 。 ) 根据 Format 参数指定的 printf 子例程格式字符串来格式化 Expr 参数指定的表达式并返回最后生成的字符串。

3.时间函数

mktime( YYYY MM DD HH MM SS[ DST]) 生成时间格式

strftime([format [, timestamp]]) 格式化时间输出,将时间戳转为时间字符串,具体格式如下:

%a 星期几的缩写(Sun)

%A 星期几的完整写法(Sunday)

%b 月名的缩写(Oct)

%B 月名的完整写法(October)

%c 本地日期和时间

%d 十进制日期

%D 日期 08/20/99

%e 日期,如果只有一位会补上一个空格

%H 用十进制表示24小时格式的小时

%I 用十进制表示12小时格式的小时

%j 从1月1日起一年中的第几天

%m 十进制表示的月份

%M 十进制表示的分钟

%p 12小时表示法(AM/PM)

%S 十进制表示的秒

%U 十进制表示的一年中的第几个星期(星期天作为一个星期的开始)

%w 十进制表示的星期几(星期天是0)

%W 十进制表示的一年中的第几个星期(星期一作为一个星期的开始)

%x 重新设置本地日期(08/20/99)

%X 重新设置本地时间(12:00:00)

%y 两位数字表示的年(99)

%Y 当前月份

%Z 时区(PDT)

%% 百分号(%)

systime() 得到时间戳,返回从1970年1月1日开始到当前时间(不计闰年)的整秒数

4.其他函数

close( Expression ) 用同一个带字符串值的 Expression 参数来关闭由 print 或 printf 语句打开的或调用 getline 函数打开的文件或管道。如果文件或管道成功关闭,则返回 0;其它情况下返回非零值。如果打算写一个文件,并稍后在同一个程序中读取文件,则 close 语句是必需的。

system(Command ) 执行 Command 参数指定的命令,并返回退出状态。等同于 system 子例程。

Expression | getline [ Variable ] 从来自 Expression 参数指定的命令的输出中通过管道传送的流中读取一个输入记录,并将该记录的值指定给 Variable 参数指定的变量。如果当前未打开将 Expression 参数的值作为其命令名称的流,则创建流。创建的流等同于调用 popen 子例程,此时 Command 参数取 Expression 参数的值且 Mode 参数设置为一个是 r 的值。只要流保留打开且 Expression 参数求得同一个字符串,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。

getline [ Variable ] 《 Expression 从 Expression 参数指定的文件读取输入的下一个记录,并将 Variable 参数指定的变量设置为该记录的值。只要流保留打开且 Expression 参数对同一个字符串求值,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。

getline [ Variable ] 将 Variable 参数指定的变量设置为从当前输入文件读取的下一个输入记录。如果未指定 Variable 参数,则 $0 记录变量设置为该记录的值,还将设置 NF、NR 和 FNR 特殊变量。

5.排序函数

asort:对数组的值进行排序,并且会丢掉原先键值;

asorti:对数组的下标进行排序。

例如

1.内置变量

a.$0

awk ’/^root/{print $0}‘ /etc/passwd #/^root/为选择表达式,$0代表是逐行

b.设置字段分隔符号(FS)

awk ’BEGIN {FS=:} /^root/ {print $1, NF}‘ /etc/passwd #FS为字段分隔符,可以自己设置,默认是空格,因为passwd里面是:分隔,所以需要修改默认分隔符。NF是字段总数,$0代表当前行记录,$1-$n是当前行,各个字段对应值。

c.记录条数(NR、FNR)

awk ’BEGIN {FS=:} {print NR, $1, FNR}‘ /etc/passwd #NR得到当前记录所在行

d.设置输出字段分隔符(OFS)

awk ’BEGIN {FS=:; OFS=~~} /^root/ {print FNR, $1, $NF}‘ /etc/passwd #OFS设置默认字段分隔符

e.设置输出行记录分隔符(ORS)

awk ’BEGIN {FS=:; ORS=~~} {print FNR, $1, $NF}‘ #ORS默认是换行符,这里修改为:~~,所有行之间用~~分隔了

f.输入参数获取(ARGC,ARGV)

awk ’BEGIN {FS=:; print ARGC=ARGC; for (k in ARGV) {print k=ARGV[k];}}‘ /etc/passwd #ARGC得到所有输入参数个数,ARGV获得输入参数内容,是一个数组

g.获得传入的文件名(FILENAME)

awk ’BEGIN {FS=:; print FILENAME} {print FILENAME}‘ /etc/passwd #FILENAME,$0-$N,NF 不能使用在BEGIN中,BEGIN中不能获得任何与文件记录操作的变量。

h.获得linux环境变量(ENVIRON)

awk ’BEGIN {print ENVIRON[PATH];}‘ /etc/passwd #ENVIRON是子典型数组,可以通过对应键值获得它的值。

i.输出数据格式设置(OFMT)

awk ’BEGIN {OFMT=%.3f; print 2/3,123.11111111;}‘ /etc/passwd #OFMT默认输出格式是:%.6g 保留六位小数,这里修改OFMT会修改默认数据输出格式

j.按宽度指定分隔符

echo 20100117054932 | awk ’BEGIN {FIELDWIDTHS=4 2 2 2 2 3} {print $1-$2-$3,$4:$5:$6}‘ #FIELDWIDTHS其格式为空格分隔的一串数字,用以对记录进行域的分隔,FIELDWIDTHS=4 2 2 2 2 2就表示$1宽度是4,$2是2,$3是2 。。.。 。这个时候会忽略:FS分隔符

k.RSTART RLENGTH

awk ’BEGIN{start=match(this is a test,/[a-z]+$/); print start, RSTART, RLENGTH }‘

awk ’BEGIN{start=match(this is a test,/^[a-z]+$/); print start, RSTART, RLENGTH }‘ #RSTART被匹配正则表达式首位置,RLENGTH匹配字符长度,没有找到为-1.

2.获取外部变量

a.获取普通的外部变量

test=’awk code‘

echo | awk ’{print test}‘ test=$test

echo | wawk ’BEGIN {print test}‘ test=$test #传入的变量可以在action中获取值,但是变量名与值放到’{action}‘后边。其中BEGIN的action是不能获得

b.BEGIN程序块的变量

test=’awk code‘

echo | awk -v test=$test ’BEGIN {print test}‘

echo | awk -v test=$test ’{print test}‘ #用-v 传入变量可以在3中类型的action 中都可以获得到,但顺序在 action前面

c.获得环境变量

awk ’BEGIN {for (i in ENVIRON) {print i=ENVIRON[i];}}‘

3.运算符

a.赋值运算符、算术运算

echo | awk ’BEGIN {a=1; b=5; c=3} {a+=5; b++; c--} END {print a, b, c, a*b}‘

b.逻辑运算符

awk ’BEGIN {a=1; b=2; print (a》5 && b《=2),(a》5 || b《=2);}‘

c.关系运算符

awk ’BEGIN{a=11;if(a 》= 9){print ok;}}‘ #》 《 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串 就会转换为字符串比较。两个都为数字 才转为数值比较。字符串比较:按照ascii码顺序比较

d.其它运算符

awk ’BEGIN {a=b; print a==b ? ok : err;}‘ #三目运算

awk ’BEGIN {a=b; arr[0]=b; arr[1]=c; print (a in arr);}‘ #判断数组中是否存在该键值

3.字符操作

a.字符串转数字

awk ’BEGIN {a=100; b=10test10; print (a+b+0);}‘

awk ’BEGIN {a=100; b=10test10; print a+b+0;}‘

b.数字转字符串

awk ’BEGIN {a=100; b=100; c=(ab); print c}‘

awk ’BEGIN {a=100; b=100; c=ab; print c}‘

c.字符串连接

awk ’BEGIN {a=a; b=b; c=ab; print c}‘

3.数组操作

a.赋值

awk ’BEGIN {tB[a]=a1; tB[b]=1;}‘

b.数组长度(length)

awk ’BEGIN {tB[a]=a1; tB[b]=1; print length(tB)}‘

awk ’BEGIN {info=it is a test; split(info,tA, ); print asort(tA);}‘ #asort对数组进行排序,返回数组长度

c.字符串分割为数组(split)

awk ’BEGIN {info=it is a test; lens=split(info,tA, ); print length(tA), lens;}‘ #length返回字符串以及数组长度,split进行分割字符串为数组,也会返回分割得到数组长度

d.数组输出

awk ’BEGIN {info=it is a test; split(info,tA, ); for(k in tA){print k, tA[k];}}‘ #forin 输出,因为数组是关联数组,默认是无序的。

awk ’BEGIN {info=it is a test; tlen=split(info,tA, ); for(k=1; k《=tlen; k++){print k, tA[k];}}‘ #如果需要得到有序数组,需要通过下标获得。数组下标是从1开始,与c数组不一样

e.判断键值是否存在

awk ’BEGIN {tB[a]=a1; tB[b]=b1; if(tB[c]!=1){print no found;}; for(k in tB){print k,tB[k];}}‘ #tB[c]没有定义,但是循环时候,发现已经存在该键值,它的值为空,这里需要注意,awk数组是关联数组,只要通过数组引用它的key,就会自动创建改序列

awk ’BEGIN {tB[a]=a1; tB[b]=b1; if( c in tB){print ok;}; for(k in tB){print k,tB[k];}}‘ #if(key in array) 通过这种方法判断数组中是否包含key键值,才能正确的判断

f.删除键值

awk ’BEGIN {tB[a]=a1; tB[b]=b1; delete tB[a]; for(k in tB){print k, tB[k];}}‘

g.二维数组

awk ’BEGIN{

for(i=1;i《=9;i++)

{

for(j=1;j《=9;j++)

{

tarr[i,j]=i*j;

print i,*,j,=,tarr[i,j];

}

}

}‘

#array[k,k2]引用获得数组内容

4.流程控制操作

a.awk ’BEGIN{

score=100;

if(score》90)

{

print 优秀;

}

else if(score》80)

{

print 良好;

}

else if(score》70)

{

print 普通;

}

else if(score》60)

{

print 及格;

}else

{

print 不及格;

}

}‘

b.awk ’BEGIN{

total=0;

while(i《=100)

{

total+=i;

i++;

}

print total;

}‘

来源:http://www.tulaoshi.com/n/20160219/1604799.html

延伸阅读
Waterlogue水彩风格照片处理工具   Waterlogue是由Tinrocket开发的一款能够将照片转换成水彩风格图画的应用程序。如果你想要将自己所拍摄的照片转换成其它特别的风格,那么这款Waterlogue将是你不错的选择。 在遇到Waterlogue之前,我一直使用由过滤器演变的能够把照片变成像素风格的应用程序Tinrocket。紧接着我发现了Popsic...
    本文是介绍管理Linux系统网络性能技巧的文章,主要介绍了route、netstat、tcpdump三种网络管理测试工具的使用方法及其可实现的功能。 route     在配置网络时,要为机器指定接收数据包时该包要经过的路径。在Linux系统中,提供一个命令route,这个命令可以为ifconfig命令配置的网卡设置静态路由。这种设置...
标签: 软件教程
灰白色有着不同于彩色的独特魅力,本文教大家如何将图片变为灰白色,而且还是在没有图片处理工具的前提下。利用的是WPS文字中自带的功能,不相信的朋友就拭目以待吧。 实现思路 首先插入需要变灰白色的图片,通过使用WPS自带的颜色灰度功能即可将图片变为灰白色,之后将其另存为其他位置即可。大家可以看到文末的灰白效果图,还不错吧。 操...
标签: 电脑入门
Linux系统操作中,用于系统监控的命令有很多(详见系统之家监控Linux系统性能的命令有哪些?),今天图老师小编要给大家介绍下Linux系统监控工具dstat的使用,一起来了解下吧。 dstat可以让你实时地看到所有系统资源,例如,你能够通过统计IDE控制器当前状态来比较磁盘利用率,或者直接通过网络带宽数值来比较磁盘的吞吐率(在相同的时间间隔...
照片处理工具 简单几招强似专业PS 大懒人必备,既想照片风格独特,又不希望操作太复杂?满足你,小编今天推荐的这款照片处理软件一定能够满足你。照片处理工具是一款很强大的图像处理工具,有了它,只需简单的三招就可以让你的照片风格独特,而且出来的效果就像专业的PS制作出来的图片一样。下面小编就为大家详细介绍,怎么通过简单的三个...

经验教程

757

收藏

66
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部