awk(一)

awk也是逐行扫描文件,寻找匹配特定模板的行,并在这些行上运行“选择”动作。

▪如果一个模板没有指定动作,这些匹配的行就被显示在屏幕上。

▪如果一个动作没有模板,所有被动作指定的行都被处理。

/> cat employees
Tom Jones         4424    5/12/66         543354
Mary Adams      5346    11/4/63         28765
Sally Chang       1654    7/22/54         650000
Billy Black         1683    9/23/44         336500
 
 1.  awk的基本格式:
awk 'pattern' filename
awk '{action}' filename
awk 'pattern {action}' filename
 
awk '/Mary/' employees   #打印所有包含模板Mary的行。
awk '{print $1}' employees 
awk '/Sally/{print $1, $2}' employees #打印包含模板Sally的行的第一、第二个域字段。
 
2.  awk的格式输出:
date | awk '{print "Month: " $2 "\nYear: " $6}'
awk '/Sally/{print "\t\tHave a nice day, " $1,$2 "\!"}' employees
awk 'BEGIN { OFMT="%.2f"; print 1.2456789, 12E-2}' 打印小数点后两位
 
▪printf
%c 打印单个ASCII字符。 Printf "The character is %c.\n" x  The character is A.
%d 打印十进制数。 Printf "The boy is %d years old.\n" y  The boy is 15 years old.
%e 打印用科学记数法表示的数。 printf("z is %e.\n",z) z is 2.3e+01.
%f 打印浮点数。 Printf "z is %f.\n" z  z is 2.300000
%o 打印八进制数。 Printf "y is %o.\n" y y is 17.
%s 打印字符串。 Printf "The name is %s.\n" $1 ; The name is Bob Smith.
%x 打印十六进制数。 Printf "y is %x.\n" y  y is f.
 
echo "Linux" | awk '{printf "|%-15s|\n", $1}' #%-15s表示保留15个字符的空间,同时左对齐。
echo "Linux" | awk '{printf "|%15s|\n", $1}'    # %-15s表示保留15个字符的空间,同时右对齐。
awk '{printf "The name is %-15s ID is %8d\n", $1,$3}' employees %8d表示数字右对齐,保留8个字符的空间
 
3.  awk中的记录和域:
awk '{print $0}' employees  #$0变量是指整条记录
 
变量NR(Number of Record),记录每条记录的编号
awk '{print NR, $0}' employees
awk '{print $0,NF}' employees
 
sed 's/[[:space:]]\+\([0-9]\)/:\1/g;w employees2' employees #根据employees生成employees2
    Tom Jones:4424:5/12/66:543354
    Mary Adams:5346:11/4/63:28765
    Sally Chang:1654:7/22/54:650000
    Billy Black:1683:9/23/44:336500
 
awk -F: '/Tom Jones/{print $1,$2}' employees2  #这里-F选项后面的字符表示分隔符。
    Tom Jones 4424
 
变量OFS(Output Field Seperator)表示输出字段间的分隔符,缺省是空格。
awk -F: '{OFS = "?"};  /Tom/{print $1,$2 }' employees2
Tom Jones?4424
 
awk '$3 < 4000 {print}' employees
 
awk '$3 < 4000 && /Sally/ {print}' employees
 
 
4.  匹配操作符:
" ~ " 用来在记录或者域内匹配正则表达式。
" !~ "表示不匹配的意思
 
awk '$1 ~ /[Bb]ill/' employees      #显示所有第一个域匹配Bill或bill的行
awk '$1 !~ /[Bb]ill/' employees     #显示所有第一个域不匹配Bill或bill的行
 
5.  awk的基本应用实例:
awk '/^north/' testfile            #打印所有以north开头的行。
awk '/^(no|so)/' testfile          #打印所有以so和no开头的行
awk '$5 ~ /\.[7-9]+/' testfile     #第五个域字段匹配包含.(点),后面是7-9的数字。
awk '$8 ~ /[0-9][0-9]$/{print $8}' testfile  #第八个域以两个数字结束的打印。
 
【awk表达式功能】 
 
变量:
awk变量在赋值时即已经完成了定义。
变量的类型可以是数字、字符串。
未初始化变量的值为0或空白字符串" ",
变量的赋值符号列表
= += -= 
*= /= %= ^=
awk '$1 ~ /Tom/ {Wage = $2 * $3; print Wage}' filename
awk ' {$5 = 1000 * $3 / $2; print}' filename

 /> cat employees
    Tom Jones        4424    5/12/66         543354
    Mary Adams      5346    11/4/63         28765
    Sally Chang       1654    7/22/54         650000
    Billy Black         1683    9/23/44         336500
 
 1.  比较表达式:
< 小于 x < y
<= 小于等于 x <= y
== 等于 x == y
!= 不等于 x != y
>= 大于等于 x >= y
> 大于 x > y
~ 匹配 x ~ /y/
!~ 不匹配 x !~ /y/
 
awk '$3 == 5346' employees        #打印第三个域等于5346的行。
awk '$3 > 5000 {print $1}' employees   #打印第三个域大于5000的行的第一个域字段。
awk '$2 ~ /Adam/' employess       #打印第二个域匹配Adam的行。
 
2.  条件表达式:
 
 /> cat testfile
    northwest     NW        Charles Main             3.0        .98        3        34
    western        WE        Sharon Gray             5.3        .97         5        23
    southwest     SW        Lewis Dalsass           2.7        .8          2        18
    southern       SO        Suan Chin                 5.1        .95        4        15
    southeast      SE        Patricia Hemenway     4.0        .7          4        17
    eastern         EA        TB Savage                 4.4        .84        5        20
    northeast      NE        AM Main Jr.                5.1       .94         3        13
    north            NO        Margot Weber           4.5       .89         5        9
    central          CT        Ann Stephens            5.7       .94         5        13
 
awk 'NR <= 3 {print ($7 > 4 ? "high "$7 : "low "$7) }' testfile #前三行,域7是否大于4,
 
3.  数学表达式:
+ 加 x + y
- 减 x - y
* 乘 x * y
/ 除 x / y
% 取余 x % y
^ 乘方 x ^ y
 
awk '/southern/{print $5 + 10}' testfile   #如果记录包含正则表达式southern,第五个域就加10并打印。
awk '/southern/{print $8 /2 }' testfile    #如果记录包含正则表达式southern,第八个域除以2并打印。
 
4.  逻辑表达式:
&& 逻辑与 a && b
|| 逻辑或 a || b
! 逻辑非 !a
 
awk '$8 > 10 && $8 < 17' testfile    #打印出第八个域的值大于10小于17的记录。
awk '$2 == "NW" || $1 ~ /south/ {print $1,$2}' testfile 打印 第二个域等于NW,或者第一个域匹配south的行 的第一、第二个域。
awk '!($8 > 13) {print $8}' testfile  #打印第八个域字段不大于13的行的第八个域。
 
5.  范围模板:
awk '/^western/,/^eastern/ {print $1}' testfile  #打印以western开头到eastern开头的记录的第一个域。
 
6.  赋值符号:
awk '$3 == "Ann" { $3 = "Christian"; print}' testfile
#找到第三个域等于Ann的记录,然后给该域重新赋值为Christian,之后再打印输出该记录。
 
awk '/Ann/{$8 += 12; print $8}' testfile 
#找到包含Ann的记录,并将该条记录的第八个域的值+=12,最后再打印输出。

  

posted @ 2019-03-20 10:15  山的那一边  阅读(131)  评论(0)    收藏  举报