一,编写awk 脚本
HELLO,WORLD
$echo 'this line of data is ignored' > test $ awk'{ print "Hello, world" }' test Hello,world
1,Awk读入一行,执行一次括号里面的动作
$ cattest2
Hello,world $ awk'{ print }' test2 Hello,world
2,print语句没有参数,只简单输出每个输入行。
$ awk‘BEGIN {print “hello,World”}’
Hello,World
BEGIN模式不需要等待输入,它在第一个输入行读入之前执行。
#test for integer, string or empty line.
/[0-9]+/{ print "That is an integer" } /[A-Za-z]+/{ print "This is a string" } /^$/{ print "This is a blank line." }
一个特殊的例子:
$ awk-f awksrc
4T Thatis an integer Thisis a string
一行可以匹配一条或多条规则
$ awk'{ print $2, $1, $3 }' names
RobinsonJohn 666-555-1111
可以使用计算值为整数的表达式来表示一个字段
复制代码代码示例:
$echo a b c d | awk 'BEGIN { one = 1; two = 2 }
>{ print $(one + two) }' c
可以使用-F来改变字段分隔符
$ awk-F"\t" '{ print $2 }' names
666-555-1111 $ awk-F"\t+" '{ print $2 }' names $ awk-F"[‘:\t]"'{ print $2 }' names
任何3个字符之一都可以被解释为字段分隔符
BEGIN{ FS = "," } # comma-delimited fields
{print $1 "-" $2 }
使用匹配规则
/MA/{ print $1 ", " $6 }
为了避免假警报,可以使用更精确的匹配
$5 ~/MA/ { print $1 ", " $6 }
还可以使用!来反转这个规则的意义
$5 !~/MA/ { print $1 ", " $6 }
表达式:
z ="Hello"
z ="Hello" "World" z =$1
以上几种都是合法的
++Add 1 to variable.
--Subtract 1 from variable. +=Assign result of addition. -=Assign result of subtraction. *=Assign result of multiplication. /=Assign result of division. %=Assign result of modulo. ^=Assign result of exponentiation.(取幂)
计算文件中空行的数目
#Count blank lines.
/^$/{ printx += 1 } x=x+1x+=1 ++x x++
这几种有什么区别?
#Count blank lines.
/^$/{ ++x } END { printx }
计算学生的平均成绩
mona70 77 85 83 70 89
john85 92 78 94 88 91 andrea89 90 85 94 90 95 jasper84 88 80 92 84 82 dunce64 80 60 60 61 62 ellis90 98 89 96 96 92 $ awk-f src2.awk grades john87.4 andrea86 jasper85.6 src2.awk #average five grades {total = $2 + $3 + $4 + $5 + $6 avg =total / 5 print$1, avg }
也可以使用print $1, total / 5
FS 定义字段分隔符,默认为一个空格
OFS 输出的字段分隔符,默认为一个空格 RS 记录分隔符,默认为一个换行符 ORS 输出的记录分隔符,默认为一个换行符 NR 行数 FNR行数,多文件操作时会重新排序 NF 输出当前输入记录的编号(字段的个数) FILENAME文件名
例如:
$ awk–F: ‘OFS=”aaa”,ORS=”bbb” {print NR,FNR,NF,FILENAME}’
/etc/passwda.txt $print NR “.”,$1, avg 1.john 87.4 2.andrea 86 3.jasper 85.6
处理多行记录
#block.awk - print first and last fields
# $1 =name; $NF = phone number BEGIN{ FS = "\n"; RS = " " } {print $1, $NF } $ awk-f block.awk phones.block JohnRobinson 696-0987 PhyllisChapman 879-0900 JeffreyWillis 914-636-0000 AliceGold (707) 724-0000 BillGold 1-707-724-0000
关系操作符和布尔操作符
<Less than
>Greater than <=Less than or equal to >=Greater than or equal to ==Equal to !=Not equal to ~Matches !~Does not match
NF ==5 NF(每个输入记录的字段数)的值和5相比较,如果结果为真,那
$5 ~/MA/ {print $1 “,”$6}
注意:关系操作符==和赋值操作符=是不同的
||Logical OR
&&Logical AND !Logical NOT NF ==6 && NR > 1
字段的数量必须等于6并且记录的编号必须大于1。
NR>1 && NF >=2 || $1 ~ /\t/
(NR>1 && NF >=2 )|| $1 ~ /\t/ !(NR> 1 && NF > 3)
获取文件的信息:
$ ls-l |awk -f src3.awk
BEGIN{ print "BYTES", "\t", "FILE" } { sum+= $5 ++filenum print$5, "\t", $8 } END {print "Total: ", sum, "bytes (" filenum " files)"}
格式化打印
printf("%d \t %s \n ", $5 , $8 )
printf("|%10s|\n","hello") 右对齐 printf("|%-10s|\n","hello") 左对齐 printf("%*.*f\n",5, 3, myvar) 宽度5 精度3 打印myvar
向脚本传递参数
awk'script' var=value inputfile
$var=root $ awk–F: -v a=$var ‘$1==a {print}’ /etc/passwd
二,条件、循环
if (avg >= 65 )
grade= "Pass" else grade= "Fail" if(avg >= 90) grade = "A" elseif (avg >= 80) grade = "B" elseif (avg >= 70) grade = "C" elseif (avg >= 60) grade = "D" else grade = "F"
这种能够连续条件只有当一个条件表达式计算结果为真时才停止求值,这时将
i = 1
while( i <= 4 ) { print$i ++i }
do 循环
BEGIN{
do { ++x printx }while ( x <= 4 ) }
for 循环
从第一个字段到最后一个字段
for (i = 1; i <= NF; i++ ) print$i 从最后一个字段到第一个字段 for (i = NF; i >= 1; i-- ) print$i
用for实现
total= 0
for(i = 2; i <= NF; ++i) #total= $2 + $3 + $4 + $5 + $6 #avg= total / 5 total+= $i avg =total / (NF - 1)
求阶乘
5!=5*4*3*2*1
fact= number for(x = number - 1 ; x > 1; x--) fact*= x
完整脚本 factorial
影响控制流
影响主输入循环 (责任编辑:IT) |