Linux-awk command

简介

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。

语法

1
2
3
awk [选项参数] 'script' var=value file(s)

awk [选项参数] -f scriptfile var=value file(s)

参数

-F fs

1
-F fs or --field-separator fs

指定输入文件折分隔符,fs 是一个字符串或者是一个正则表达式。

-v var=value

1
-v var=value or --asign var=value

赋值一个用户定义变量。

-f scriptfile

1
-f scripfile or --file scriptfile

从脚本文件中读取 awk 命令。

-mf nnn

1
-mf nnn and -mr nnn

对 nnn 值设置内在限制,-mf 选项限制分配给 nnn 的最大块数目;-mr 选项限制记录的最大数目。
这两个功能是 Bell 实验室版 awk 的扩展功能,在标准 awk 中不适用。

-W compact

1
-W compact or --compat, -W traditional or --traditional

在兼容模式下运行 awk。所以 gawk 的行为和标准的 awk 完全一样,所有的 awk 扩展都被忽略。

-W copyleft

1
-W copyleft or --copyleft, -W copyright or --copyright

打印简短的版权信息。

-W help

1
-W help or --help, -W usage or --usage

打印全部 awk 选项和每个选项的简短说明。

-W lint

1
-W lint or --lint

警告可疑或不移植到其他的 awk 实现的结构。

-W lint-old

1
-W lint-old or --lint-old

打印不能向传统 unix 平台移植的结构的警告。

-W posix

1
-W posix

打开兼容模式。
但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符=不能代替^和^=;fflush无效。

-W re-interval

1
-W re-interval or --re-inerval

允许间隔正则表达式的使用,参考( grep 中的 Posix 字符类),如括号表达式 [[:alpha:]]。

-W source program-text

1
-W source program-text or --source program-text

使用 program-text 作为源代码,可与 -f 命令混用。

-W version

1
-W version or --version

打印 bug 报告信息的版本。


基本用法

log.txt 内容如下:

1
2
3
4
2 this is a test
3 Are you like awk
This's a test
10 There are orange,apple,mongo
  1. 每行按空格或 TAB 分割,输出文本中的 1、4 项

    1
    2
    3
    4
    5
    $ awk '{print $1,$4}' log.txt
    2 a
    3 like
    This's
    10 orange,apple,mongo
  2. 指定分隔字符串,使用 , 分割

    1
    2
    3
    4
    5
    $ awk -F "," '{print $1,$2}' log.txt
    2 this is a test
    3 Are you like awk
    This's a test
    10 There are orange apple
  3. 指定变量

    1
    2
    3
    4
    5
    $ awk -v a=1 '{print $1,$1+a}' log.txt
    2 3
    3 4
    This's 1
    10 11
  4. 使用脚本

    1
    $ awk -f cal.awk log.txt

高级用法

内建变量

  • $n:当前记录的第 n 个字段,字段间由 FS 分隔。
  • $0:完整的输入记录。
  • ARGC:命令行参数的数目。
  • ARGIND:命令行中当前文件的位置(从 0 开始算)。
  • ARGV:包含命令行参数的数组。
  • CONVFMT:数字转换格式(默认值为 %.6g ) ENVIRON 环境变量关联数组。
  • ERRNO:最后一个系统错误的描述。
  • FIELDWIDTHS:字段宽度列表(用空格键分隔)。
  • FILENAME:当前文件名。
  • FNR:各文件分别计数的行号。
  • FS:字段分隔符(默认是任何空格)。
  • IGNORECASE:如果为真,则进行忽略大小写的匹配。
  • NF:一条记录的字段的数目。
  • NR:已经读出的记录数,就是行号,从 1 开始。
  • OFMT:数字的输出格式(默认值是 %.6g )。
  • OFS:输出字段分隔符,默认值与输入字段分隔符一致。。
  • ORS:输出记录分隔符(默认值是一个换行符)。
  • RLENGTH:由 match 函数所匹配的字符串的长度。
  • RS:记录分隔符(默认是一个换行符)。
  • RSTART:由 match 函数所匹配的字符串的第一个位置。
  • SUBSEP:数组下标分隔符(默认值是 /034)。
  1. 输出顺序号 NR, 匹配文本行号

    1
    2
    3
    4
    5
    $ awk '{print NR,FNR,$1,$2,$3}' log.txt
    1 1 2 this is
    2 2 3 Are you
    3 3 This's a test
    4 4 10 There are
  2. 指定输出分割符

    1
    2
    3
    4
    5
    $  awk '{print $1,$2,$5}' OFS=" $ "  log.txt
    2 $ this $ test
    3 $ Are $ awk
    This's $ a $
    10 $ There $

正则表达式

~ 表示模式开始。// 内是模式。

  1. 输出包含 re 的行

    1
    2
    3
    $ awk '/re/ ' log.txt
    3 Are you like
    10 There are orange,apple,mongo
  2. 忽略大小写

    1
    2
    3
    $ awk 'BEGIN{IGNORECASE=1} /this/' log.txt
    2 this is a test
    This's a test

运算符

  • = += -= *= /= %= ^= **=:赋值
  • ?::C条件表达式
  • ||:逻辑或
  • &&:逻辑与
  • ~ !~:匹配正则表达式和不匹配正则表达式
  • < <= > >= != ==:关系运算符
  • 空格:连接
  • + -:加,减
  • * / %:乘,除与求余
  • + - !:一元加,减和逻辑非
  • ^ ***:求幂
  • ++ --:增加或减少,作为前缀或后缀
  • $:字段引用
  • in:数组成员
  1. 过滤第一列大于 2 的行

    1
    2
    3
    4
    $ awk '$1>2' log.txt
    3 Are you like
    This's a test
    10 There are orange,apple,mongo
  2. 过滤第一列大于 2 并且第二列等于 Are 的行

    1
    2
    $ awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt
    3 Are you

脚本

关于 awk 脚本,我们需要注意两个关键词 BEGINEND

  • BEGIN { 这里面放的是执行前的语句 }
  • END { 这里面放的是处理完所有的行后要执行的语句 }
  • { 这里面放的是处理每一行时要执行的语句 }
  1. 测试文件内容如下:

    1
    2
    3
    4
    5
    6
    $ cat score.txt
    Marry 2143 78 84 77
    Jack 2321 66 78 45
    Tom 2122 48 77 71
    Mike 2537 87 97 95
    Bob 2415 40 57 62
  2. 脚本文件如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    $ cat cal.awk
    #!/bin/awk -f
    #运行前
    BEGIN {
    math = 0
    english = 0
    computer = 0

    printf "NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
    printf "---------------------------------------------\n"
    }
    #运行中
    {
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
    }
    #运行后
    END {
    printf "---------------------------------------------\n"
    printf " TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
    }
  3. 执行结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ awk -f cal.awk score.txt
    NAME NO. MATH ENGLISH COMPUTER TOTAL
    ---------------------------------------------
    Marry 2143 78 84 77 239
    Jack 2321 66 78 45 189
    Tom 2122 48 77 71 196
    Mike 2537 87 97 95 279
    Bob 2415 40 57 62 159
    ---------------------------------------------
    TOTAL: 319 393 350
    AVERAGE: 63.80 78.60 70.00

好玩的示例

  1. 打印九九乘法表
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'
    1x1=1
    1x2=2 2x2=4
    1x3=3 2x3=6 3x3=9
    1x4=4 2x4=8 3x4=12 4x4=16
    1x5=5 2x5=10 3x5=15 4x5=20 5x5=25
    1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
    1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
    1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
    1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81

工作原理

AWK 工作原理


参考

官方手册


个人备注

此博客内容均为作者学习所做笔记,侵删!
若转作其他用途,请注明来源!