文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>awk 学习笔记 -- by wdx

awk 学习笔记 -- by wdx

时间:2007-10-17  来源:rha030

一、awk的作用
现在有这样一个表coins.txt,它的每一列的内容分别是 metal、weight in ounces、 date minted、country of origin和description,内容如下:

   gold 1 1986 USA American Eagle
   gold 1 1908 Austria-Hungary Franz Josef 100 Korona
   silver 10 1981 USA ingot
   gold 1 1984 Switzerland ingot
   gold 1 1979 RSA Krugerrand
   gold 0.5 1981 RSA Krugerrand
   gold 0.1 1986 PRC Panda
   silver 1 1986 USA Liberty dollar
   gold 0.25 1986 USA Liberty 5-dollar piece
   silver 0.5 1986 USA Liberty 50-cent piece
   silver 1 1987 USA Constitution dollar
   gold 0.25 1987 USA Constitution 5-dollar piece
   gold 1 1988 Canada Maple Leaf



如果想查看所有金币的信息,可以

awk '/gold/' coins.txt


如果想查看金币的日期和国家,可以:

awk '/gold/{print $3 " " $4}' coins.txt

注意上面的" ",如果不加这个空格,awk会把连续的两个字符串连接到一起,也就是把时间和国家连成一个字串,另外$3和$4分别表法当前行的第3、4个域。
如果想查看1980以前的货币,可以:

awk '{if ($3 < 1980) print}'  coins.txt

print默认打印当前行,相当于print $0,$0相当于整行

如果想统计有多少种货币,可以:

awk 'END {print NR,"coins"}'  coins.txt

即在awk对文本扫描完成后,打印出NR的值,NR表示当前行的行号, 这里就是最后一行了。

如果想统计所有金币的价值,可以:

awk '/gold/ {ounces += $2} END {print "value = $" 425*ounces}' coins.txt


即把所有金币的重量加到一起,再乘以单位金的价格就得到总的价值。

二、awk的命令行:

awk -Fch 'spcecial_lines{cmd1;cm2...}' processed_txt


这里:
  • -F指定域(列)之间的分隔符为ch,awk默认的分隔符是空格或者TAB,但有些文件的分隔符可能是":"等,比如/etc/passwd文件
  • spcecial_lines指定文本中需要处理的行,如果没有指定表示对文本中的所有行运行后面的cmd,指定的方法有多种spcecial_lines,后面会具体说明。
  • 如果没有指定命令,默认执行print,即打印当前行,每个命令以;隔开
  • 如果没有指定被处理文件,则默认从标准输入读取,直到ctrl+D结束,另外可以指定多被处理文件,awk会把多个文件产生的输出连在一起。
另外,还可以把awk的脚本写到一个文件里,然后在命令行里通过使用-f program_file选项来运行。还可以在命令行里定义awk的变量,比如

awk 'cmd' var1=value1 processed_txt


需要注意的是如果awk的命令是在命令中指定,需要加上''避免shell解释。
三、 awk的语法

1.spcecial_lines的指定,awk中可以通过多种方式来指定需要处理的行
  • 使用正则表达式处理那些含有和模式匹配的文本的行,比如上面的“/gold/”就可以看作是一种简单的正则表达式,至于其他的正则表达式不再深入,和一般的正则表达式的语法相同
  • 处理某一个域是符合某种模式的,比如

awk '$1~/^gold/{print $2}' coin.txt

或者不符合:$1!~/^gold/
  • 通过行号指定:NR==10,这里可以使用<,<=.,==,!=,>=,>等关系符得到相应的行的范围,另外NF==0,表示所有空行,NF是当前行的域的个数
  • 指定连结的行,可以用/^foo/,/^bar/或者NR==10,NR==20来确定一个范围
  • 指定行的条件可以用逻辑关系符连接,比如

((NR>=30)&&($1=="France")) || ($1 == "Norway")

表示30行以后的以France开始的行,或者所有的以Norway开始的行。
  • 比较特殊的是前面看到的BEGIN和END,这两个标志分别指定awk在处理所有行之前和之后执行相应的命令,BEGIN多用于变量的初始化,而END而用于统计一些信息。
2.awk的变量
    awk是一种弱类型的编程语言,它在使用变量时不需要先声明。awk中根据变量值的不同,数字和字符操作可以分为以下几种情况:
  • 数字串,符合以下数字形式的,不管是否加“”:

789 3.141592654 +67 +4.6E3 -34 -2.1e-2

值为这种形式的变量既可以参与数值操作也可以参与字符串,比如文件test的内容为“PI  3.1415”,执行下面的操作

awk '{print $2+1}' test

结果是4.1415,也可以执行字符串操作:

awk '{print substr($2,1,4)}' test

结果是3.14

awk 'BEGIN{var="1234";print var+1}' test

结果是1235
  • 加“”的除了数字以外的字符串,比如"foo",这种变量只能参与字符串操作,如果放在数字操作里它的值为0,比如:

awk 'BEGIN{var="foo";print var+1}' test                             

结是为1,这就为我们分区文本中的一个域是否符合数字的形式提供了一个办法,比如需要针对第一个域是大于100的数那些行操作,可以使用下面的条件:

((( $1 + 0 ) == $1 ) && ( $1 > 100 ))

如果不加上前面判断是否为数字的条件,那么后边的数值比较的结果是不确定的,因为$1可能不是数字形式的。
  • 不加""的除了数字以外的字符串,变量的值会被认为是0,打印这个变量输出是空行

awk 'BEGIN{var=foo;if(var==0) printf("yes\n");print var}' test

它的输出是yes后面加上一个空行。
  •  另外,awk提供了一些已经定义好的变量:
NR: 当前行号
NF: 当前行的域的个数,最后一个域用$NF
FILENAME: 被处理的文件名
FS: ”field separator“,域分隔符,默认是空格和TAB
RS: "record separator" 记录的分隔符,默认是换行
OFS: 输出文本中的域分隔符,默认是空格
ORS:输出文本中的记录分隔符,默认是换行
OFMT:浮点数的输出格式,默认是"%.6g"

3. awk的数组
awk的数组不需要声明,也不需要指定大小,并且索引是从1开始的,另外索引不一定是数字,也可以是字符串,即一种关联数组。使用格式如下:

some_array[1], some_array[2], some_array[3]
或者
debts["Kim"], debts["Roberto"], debts["Vic"] ...


使用数组的一个例子,把/etc/passwd文件中的第2列,换成/etc/shadow的第2列

awk 'BEGIN{OFS=FS=":"} NR==FNR{a[$1]=$2}NR>FNR{$2=a[$1];print}' shadow passwd


这里的FNR是针对每个文件计数的,而NR从第一个文件的第一个记录开始直到最后一个文件的最后一条记录统一计数,这样NR>NNR限定的就是第2个文件了,上面这个命令就是先把/etc/shadow的第2列保存到数组a中,然后把/etc/passwd的第2列换成数组中的值,数组a的索引是$1,即使这两个文件中记录的顺序不同也可以直接实现需求。

4.awk的数值运算和字符串操作
awk的数值操作基本和C语言相同:
Arithmetic operations:
 + Addition.
- Subtraction.
* Multiplication.
/ Division.
% Mod.
++ Increment.
-- Decrement.
Shorthand assignments:
 x += 2 -- is the same as: x = x + 2
x -= 2 -- is the same as: x = x - 2
x *= 2 -- is the same as: x = x * 2
x /= 2 -- is the same as: x = x / 2
x %= 2 -- is the same as: x = x % 2

另外还有几个用于数值操作的函数:

sqrt() Square root.
log() Base \Ie\i log.
exp() Power of \Ie\i.
int() Integer part of argument.

字符操作的函数有:
  • length()

    Length of string.

  • substr(<string>,<start of substring>,<max length of substring>)

    Get substring.

  • split(<string>,<array>,[<field separator>])

    Split string into array, with initial array index being 1.

  • index(<target string>,<search string>)

    Find index of search string in target string.

  • sprintf()

    Perform formatted print into string.

5.awk的控制结构
awk作为一种编程语言,提供了程序流的控制结构和C语言十分相似:
 
if (<condition>) <action 1> [else <action 2>]
while (<condition>) <action>
for (<initial action>;<condition>;<end-of-loop action>) <action>
Scanning through an associative array with "for":
 for (<variable> in <array>) <action>
Unconditional control statements:
 break Break out of "while" or "for" loop.
continue Perform next iteration of "while" or "for" loop.
next Get and scan next line of input.
exit Finish reading input and perform END statements.
6.awk的输出格式
printf可以用于格式化输出,使用格式:
%[<number>]<format code>
其中的number:
前面的-指定左对齐,否则是右对齐
整数部分对于输出字符串指定的输出最少所占宽度,如果输出内容长度超过这个值会超出这个宽度
小数部分对于浮点数指定小数部分的位数,对于字符串指定最多占的宽度
前面的0表明剩余空间用0补全


   x = "Baryshnikov"
   printf("[%3s]\n",x) yields: [Baryshnikov]
   printf("[%16s]\n",x) yields: [ Baryshnikov]
   printf("[%-16s]\n",x) yields: [Baryshnikov ]
   printf("[%.3s]\n",x) yields: [Bar]
   printf("[%16.3s]\n",x) yields: [ Bar]
   printf("[%-16.3s]\n",x) yields: [Bar ]
   printf("[%016s]\n",x) yields: [00000Baryshnikov]
   printf("[%-016s]\n",x) yields: [Baryshnikov ]


参考:http://www.vectorsite.net/tsawk.html
     http://www.chinaunix.net/jh/24/577044.html
另外一个不错的参考:http://www.chinaitpower.com/A/2003-02-14/50128.html
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载