必威体育Betway必威体育官网
当前位置:首页 > IT技术

awk命令

时间:2019-10-03 06:46:02来源:IT技术作者:seo实验室小编阅读:63次「手机版」
 

awk命令

文章目录

awk命令

逐行处理文本数据

基本命令

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

选项参数说明:

  • -F fs or --field-separator fs

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

  • -v var=value or --asign var=value

    赋值一个用户定义变量。

  • -f scripfile or --file scriptfile

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

  • -mf nnn and -mr nnn

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

  • -W compact or --compat, -W traditional or --traditional

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

  • -W copyleft or --copyleft, -W copyright or --copyright

    打印简短的版权信息。

  • -W help or --help, -W usage or --usage

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

  • -W lint or --lint

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

  • -W lint-old or --lint-old

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

  • -W posix

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

  • -W re-Interval or --re-inerval

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

  • -W source program-text or --source program-text

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

  • -W version or --version

    打印bug报告信息的版本。

基本用法

log.txt文本内容如下:

2 this is a test
3 Are you like awk
This's a test
10 There are orange,APPle,mongo

用法一: awk '{[pattern] action}' {filenames} # 行匹配语句 awk ‘’ 只能用单引号

# 每行按空格或TAB分割,输出文本中的1、4项
 $ awk '{print $1,$4}' log.txt
 ---------------------------------------------
 2 a
 3 like
 This's
 10 orange,apple,mongo
 # 格式化输出
 $ awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
 ---------------------------------------------
 2        a
 3        like
 This's
 10       orange,apple,mongo

用法二: awk -F #-F相当于内置变量FS, 指定分割字符

# 使用","分割
 $  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
 
 # 或者使用内建变量
 $ awk 'BEGIN{FS=","} {print $1,$2}'     log.txt
 ---------------------------------------------
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 
 # 使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割.多个分隔符志杰写在[]里面
 $ awk -F '[ ,]'  '{print $1,$2,$5}'   log.txt
 ---------------------------------------------
 2 this test
 3 Are awk
 This's a
 10 There apple

用法三: awk -v # 设置变量,变量名与v紧挨

$ awk -va=1 '{print $1,$1+a}' log.txt
 ---------------------------------------------
 2 3
 3 4
 This's 1
 10 11
 
 $ awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
 ---------------------------------------------
 2 3 2s
 3 4 3s
 This's 1 This'ss
 10 11 10s

用法四: awk -f {awk脚本} {文件名}

awk -f cal.awk log.txt

一般的逻辑运算符均可用,具体参见http://www.runoob.com/linux/linux-comm-awk.html

运算符 描述
= += -= *= /= %= ^= **= 赋值
?: C条件表达式
~ ~! 匹配正则表达式和不匹配正则表达式
空格 连接
^ *** 求幂
$ 字段引用
in 数组成员
#过滤第一列大于2的行
$ awk '$1>2' log.txt    #命令
#输出
3 Are you like awk
This's a test
10 There are orange,apple,mongo

#过滤第一列等于2的行
$ awk '$1==2 {print $1,$3}' log.txt    #命令
#输出
2 is

#过滤第一列大于2并且第二列等于'Are'的行
$ awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt    #命令
#输出
3 Are you

内建变量

8个常用内建变量参考http://www.runoob.com/w3cnote/8-awesome-awk-built-in-variables.html

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

当awk读取多个文件时,NR 代表的是当前输入所有文件的全部记录数,而 FNR 则是当前文件的记录数

$ awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1         5    1
log.txt    2    2         5    2
log.txt    2    3         3    3
log.txt    2    4         4    4

$ awk -F\' 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1    '    1    1
log.txt    2    2    '    1    2
log.txt    2    3    '    2    3
log.txt    2    4    '    1    4

# 输出顺序号 NR, 匹配文本行号
$ 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

# 指定输出分割符
$  awk '{print $1,$2,$5}' OFS=" $ "  log.txt
---------------------------------------------
2 $ this $ test
3 $ Are $ awk
This's $ a $
10 $ There $

使用正则,字符串匹配

# 输出第二列包含 "th",并打印第二列与第四列
$ awk '$2 ~ /th/ {print $2,$4}' log.txt
---------------------------------------------
this a

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

# 输出包含"re" 的行
$ awk '/re/ ' log.txt
---------------------------------------------
3 Are you like awk
10 There are orange,apple,mongo

忽略大小写

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

模式取反

$ awk '$2 !~ /th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo

$ awk '!/th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo

awk脚本

awk工作原理

参考http://www.runoob.com/w3cnote/awk-work-principle.html

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

  • BEGIN{ 这里面放的是执行前的语句 }
  • {这里面放的是处理每一行时要执行的语句}
  • END {这里面放的是处理完所有的行后要执行的语句 }

1、通过关键字 BEGIN 执行 BEGIN 块的内容,即 BEGIN 后花括号 {} 的内容。

2、完成 BEGIN 块的执行,开始执行body块。

3、读入有 \n 换行符分割的记录。

4、将记录按指定的域分隔符划分域,填充域,$0 则表示所有域(即一行内容),11 表示第一个域,1表示第一个域,n 表示第 n 个域。

5、依次执行各 BODY 块,pattern 部分匹配该行内容成功后,才会执行 awk-commands 的内容。

6、循环读取并执行各行直到文件结束,完成body块执行。

7、开始 END 块执行,END 块可以输出最终结果。

开始块(BEGIN)

开始块就是在程序启动的时候执行的代码部分,并且它在整个过程中只执行一次。

一般情况下,我们可以在开始块中初始化一些变量。

BEGIN 是 AWK 的关键字,因此它必须是大写的。

注意:开始块部分是可选的,你的程序可以没有开始块部分。

主体块(BODY)

对于每一个输入的行都会执行一次主体部分的命令。

默认情况下,对于输入的每一行,AWK 都会执行命令。但是,我们可以将其限定在指定的模式pattern中。

注意:在主体块部分没有关键字存在。

结束块(END)

结束块是在程序结束时执行的代码。 END 也是 AWK 的关键字,它也必须大写。 与开始块相似,结束块也是可选的。

具体用法

假设有这么一个文件(学生成绩表):

$ 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

awk脚本如下:

$ 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
}

执行结果:

$ 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

计算文件大小

$ ls -l *.txt | awk '{sum+=$6} END {print sum}'
--------------------------------------------------
666581

从文件中找出长度大于80的行

awk 'length>80' log.txt

打印九九乘法表

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")}'

AWK 数组

AWK 可以使用关联数组这种数据结构,索引可以是数字或字符串。

AWK关联数 组也不需要提前声明其大小,因为它在运行时可以自动的增大或减小。

数组使用的语法格式:array_name[index]=value

创建数组

#如何创建数组以及如何访问数组元素:
$ awk 'BEGIN {
sites["runoob"]="www.runoob.com";
sites["Google"]="www.google.com"
print sites["runoob"] "\n" sites["google"]
}'
#执行以上命令,输出结果为:
www.runoob.com
www.google.com

使用如下格式访问数组元素:array_name[index]

删除数组元素

使用 delete 语句来删除数组元素,语法格式:delete array_name[index]

#数组中的 google 元素被删除(删除命令没有输出):
$ awk 'BEGIN {
sites["runoob"]="www.runoob.com";
sites["google"]="www.google.com"
delete sites["google"];
print fruits["google"]
}'

多维数组

AWK 本身不支持多维数组,不过我们可以很容易地使用一维数组模拟实现多维数组。

如下示例为一个 3x3 的三维数组:

100 200 300

400 500 600

700 800 900

array[0][0] 存储 100,array[0][1] 存储 200 ,依次类推。为了在 array[0][0] 处存储 100, 我们可以使用如下语法: array[“0,0”] = 100。使用了 0,0 作为索引,但是这并不是两个索引值。事实上,它是一个字符串索引 0,0。

$ awk 'BEGIN {
array["0,0"] = 100;
array["0,1"] = 200;
array["0,2"] = 300;
array["1,0"] = 400;
array["1,1"] = 500;
array["1,2"] = 600;

# 输出数组元素
print "array[0,0] = " array["0,0"];
print "array[0,1] = " array["0,1"];
print "array[0,2] = " array["0,2"];
print "array[1,0] = " array["1,0"];
print "array[1,1] = " array["1,1"];
print "array[1,2] = " array["1,2"];
}'

执行上面的命令可以得到如下结果

array[0,0] = 100
array[0,1] = 200
array[0,2] = 300
array[1,0] = 400
array[1,1] = 500
array[1,2] = 600

AWK 条件语句与循环

与一般语言类似

条件语句

if语句

if (condition)
    action
 或者
 if (condition)
{
    action-1
    action-1
    .
    .
    action-n
} 

判断数字是奇数还是偶数:

$ awk 'BEGIN {num = 10; if (num % 2 == 0) printf "%d 是偶数\n", num }'

IF - ELSE 语句

if (condition)
    action-1
else
    action-2

在条件语句 condition 为 true 时只需 action-1,否则执行 action-2

$ awk 'BEGIN {
    num = 11; 
    if (num % 2 == 0) printf "%d 是偶数\n", num; 
    else printf "%d 是奇数\n", num 
}'
输出结果为:
11 是奇数

IF - ELSE - IF

可以创建多个 IF - ELSE 格式的判断语句来实现多个条件的判断:

$ awk 'BEGIN {
a=30;
if (a==10)
  print "a = 10";
else if (a == 20)
  print "a = 20";
else if (a == 30)
  print "a = 30";
}'
输出结果为:
a = 30

循环

For

For 循环的语法如下:

for (initialisation; condition; increment/decrement)
    action

for 语句首先执行初始化动作( initialisation ),然后再检查条件( condition )。如果条件为真,则执行动作( action ),然后执行递增( increment )或者递减( decrement )操作。只要条件为 true 循环就会一直执行。每次循环结束都会进条件检查,若条件为 false 则结束循环。

#使用 For 循环输出数字 1 至 5:
$ awk 'BEGIN { for (i = 1; i <= 5; ++i) print i }'

while

While 循环的语法如下:

while (condition)
    action

While 循环首先检查条件 condition 是否为 true ,若条件为 true 则执行动作 action。此过程一直重复直到条件 condition 为 flase 才停止。

$ awk 'BEGIN {i = 1; while (i < 6) { print i; ++i } }'

Break

break 用以结束循环:

#当计算的和大于 50 的时候使用 break 结束循环:
$ awk 'BEGIN {
   sum = 0; for (i = 0; i < 20; ++i) { 
      sum += i; if (sum > 50) break; else print "Sum =", sum 
   } 
}'

Continue

Continue 语句用于在循环体内部结束本次循环,从而直接进入下一次循环迭代

#输出 1 到 20 之间的偶数:
$ awk 'BEGIN {for (i = 1; i <= 20; ++i) {if (i % 2 == 0) print i ; else continue} }'

Exit

Exit 用于结束脚本程序的执行。

该函数接受一个整数作为参数表示 AWK 进程结束状态。 如果没有提供该参数,其默认状态为 0。

#当和大于 50 时结束 AWK 程序。
$ awk 'BEGIN {
   sum = 0; for (i = 0; i < 20; ++i) {
      sum += i; if (sum > 50) exit(10); else print "Sum =", sum 
   } 
}'

#检查一下脚本执行后的返回状态:
$ echo $?

#执行上面的命令可以得到如下的结果:
10

AWK 用户自定义函数

用户自定义函数的语法格式为:

function function_name(argument1, argument2, ...)
{
    function body
}
  • function_name 是用户自定义函数的名称。函数名称应该以字母开头,其后可以是数字、字母或下划线的自由组合。AWK 保留的关键字不能作为用户自定义函数的名称。
  • 自定义函数可以接受多个输入参数,这些参数之间通过逗号分隔。参数并不是必须的。我们也可以定义没有任何输入参数的函数。
  • function body 是函数体部分,它包含 AWK 程序代码。

文件 functions.awk 代码如下:

# 返回最小值
function find_min(num1, num2)
{
  if (num1 < num2)
    return num1
  return num2
}

# 返回最大值
function find_max(num1, num2)
{
  if (num1 > num2)
    return num1
  return num2
}

# 主函数
function main(num1, num2)
{
  # 查找最小值
  result = find_min(10, 20)
  print "Minimum =", result

  # 查找最大值
  result = find_max(10, 20)
  print "Maximum =", result
}

# 脚本从这里开始执行
BEGIN {
  main(10, 20)
}  

执行 functions.awk 文件,可以得到如下的结果:

$ awk -f functions.awk 
Minimum = 10
Maximum = 20

AWK 内置函数

具体参考http://www.runoob.com/w3cnote/awk-built-in-functions.html

算数函数

字符串函数

时间函数

位操作函数

其它函数

相关阅读

打补丁文件时候patch -p1命令的含义

其实patch在具体使用的时候是不用指定原文件的,因为补丁文件中都已经记载了原文件的路径和名称。patch足够聪明可以认出来。但是有

VIM系列-1-常用命令集锦

话说笔者早就想对这方面来个“大扫除”拉。学习有多种方式,你可以零碎的学习,也可以系统的学习。因为命令很琐碎,如果每次用的时候再

进入注册表一些常用的命令大全汇总

进入注册表一些常用的命令大全汇总 进入注册表有很多的命令.如果很熟悉了.使用起来也很方便的我们可以点击桌面左下角的开始>>运

LaTeX 各种命令,符号

函数、符号及特殊字符 声调 语法 效果 语法 效果 语法 效果 \bar{x} \acute{\eta} \check{\alpha} \grave{\et

curl命令调试接口

一.场景再现 大家好,很快就过年了,在这里先祝各位新年快乐,阖家欢乐!现在我们切入主题,在我们平时开发接口完成后,需要上线联调接口,而接

分享到:

栏目导航

推荐阅读

热门阅读