澳门新萄京appawk知识点总括,awk知识点全回看

作者: 计算机操作系统  发布:2019-11-08

find+xargs+grep+sed+awk系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html**

本文目录:
1.awk简介和基本语法格式
2.print和printf格式化输出
3.输入行的字段分隔符和行分隔符
4.BGEIN和END
5.数组
6.流程控制语句
  6.1 条件判断语句
  6.2 while循环
  6.3 do循环
  6.4 for循环
7.更完整的awk程序格式和表达式
8.awk中的变量
9.awk中的内置函数
10.自定义函数
11.getline函数
12.向awk传递变量


1. awk简介和基本语法格式

Awk自动地搜索输入文件,并把每一个输入行切分成字段。许多工作都是自动完成的,例如读取每个输入行、字段分割、存储管理、初始化等。在AWK中不需声明变量数据类型,它内置字符串类型和数值类型。

一般来说,在CentOS上安装的awk默认是gawk。它的调用格式为:

awk [OPTIONS] -f program_file [--] filename_list
awk [OPTIONS] [--] program filename_list

program是awk程序的重中之重,称为awk的程序,它的格式为PATTERN{ACTIONS}。awk每读入一行,都会先与PATTERN做匹配比较,当找到符合条件的数据就执行对应的ACTION。

其中PATTERN或ACTIONS二者可省一。省略PATTERN时表示对所有行都执行ACTIONS,省略ACTIONS表示对符合条件的行执行默认的print动作。因为二者可省一,所以用大括号{}将ACTIONS部分包围起来,以区分PATTERN和ACTIONS。

一个简单的例子,输出/etc/passwd中用户shell为/bin/bash的用户名,其中使用"-F"选项指定冒号作为分隔符。

awk -F':' '$7 == "/bin/bash"{print "who use bash shell: ",$1}' /etc/passwd

其中位置变量$1,$2...为该行的第几个字段,"$0"表示整行。

如果要输出多个字段,则字段之间使用逗号","分隔,例如{print $1,$5}但输出时,仍默认以空格分隔各输出字段。

如果action为print $1 $5,则结果会将"$1"和"$5"拼接在一起,因为空格是awk中的拼接字符。例如变量赋值name = "abc" "bcd"等价于name="abcbcd"。其实不算是拼接符,而是因为awk会忽略任何不被引号包围的空白。

1. awk简介和基本语法格式

Awk自动地搜索输入文件,并把每一个输入行切分成字段。许多工作都是自动完成的,例如读取每个输入行、字段分割、存储管理、初始化等。在AWK中不需声明变量数据类型,它内置字符串类型和数值类型。

一般来说,在CentOS上安装的awk默认是gawk。它的调用格式为:

awk [OPTIONS] -f program_file [--] filename_list
awk [OPTIONS] [--] program filename_list

program是awk程序的重中之重,称为awk的程序,它的格式为PATTERN{ACTIONS}。awk每读入一行,都会先与PATTERN做匹配比较,当找到符合条件的数据就执行对应的ACTION。

其中PATTERN或ACTIONS二者可省一。省略PATTERN时表示对所有行都执行ACTIONS,省略ACTIONS表示对符合条件的行执行默认的print动作。因为二者可省一,所以用大括号{}将ACTIONS部分包围起来,以区分PATTERN和ACTIONS。

一个简单的例子,输出/etc/passwd中用户shell为/bin/bash的用户名,其中使用"-F"选项指定冒号作为分隔符。

awk -F':' '$7 == "/bin/bash"{print "who use bash shell: ",$1}' /etc/passwd

其中位置变量$1,$2...为该行的第几个字段,"$0"表示整行。

如果要输出多个字段,则字段之间使用逗号","分隔,例如{print $1,$5}但输出时,仍默认以空格分隔各输出字段。

如果action为print $1 $5,则结果会将"$1"和"$5"拼接在一起,因为空格是awk中的拼接字符。例如变量赋值name = "abc" "bcd"等价于name="abcbcd"。其实不算是拼接符,而是因为awk会忽略任何不被引号包围的空白。

2.print和printf格式化输出

awk使用print和printf输出数据,不仅可以输出到标准输出中,还可以重定向到文件中,使用管道传递给另一个命令。

  1. print
    将 $0 打印到标准输出。等价于print $0
  2. print expression, expression, …
    打印各个 expression, expression 之间由 OFS 分开, 由 ORS 终止
  3. print expression,expression,… > filename
    文件名filename必须使用双引号包围,否则被当作变量。且文件只会被打开一次。
  4. print expression,expression,… >> filename
  5. print expression,expression,… | command
    将数据传递给系统命令。命令需要使用双引号包围。
  6. printf(format,expression,expression,…)
  7. printf(format,expression,expression,…) > filename
  8. printf(format,expression,expression,…) >> filename
  9. printf(format,expression,expression,…) | command
  10. close(filename), close( command)
    断开 print 与 filename (或 command) 之间的连接
  11. system(command)
    执行 command; 函数的返回值是 command 的退出状态

如果print或printf的参数列表中含有操作符,则需要使用括号包围,否则容易产生歧义。如:

print($1, $3) > ($3 > 100 ? "bigpop" : "smallpop")
print $1, ($2 > $3) 

执行系统命令的方式,可以通过管道的方式,也可以通过system()函数。注意包围命令的引号加的位置。

awk 'BEGIN{name="ma long shuai";print (1,2,3,4) | "echo " name}'
awk 'BEGIN{while (("fdisk -l" | getline) >0){print $0}}'
awk 'BEGIN{system("fdisk -l")}'
awk 'BEGIN{name="ma long shuai";system("echo " name)}'

printf命令可以输出更格式化的数据。

printf(format, value1, value2, ... , valueN)

format是一个字符串,包含按字面输出的纯文本,还包含输出格式,格式使用格式说明符"%"描述,后面跟着几个字符,这些字符控制一个value的输出格式。第一个"%"描述value1的输出格式,第二个"%"描述value2的输出格式,依次类推。因此,"%"的数量应该和被输出的value数量一样多。

例如:

{ printf("total pay for %s is $%.2fn", $1, $2 * $3) }
{ printf("%-8s $%6.2fn", $1, $2 * $3) }

第一个程序包含了两个要格式化的value,分别是"$1"和"$2 * $3"。这两个value的输出格式分别被"%s"和"%.2f"描述,前者表示按字符串格式输出"$1",后者表示按小数值格式输出"$2 * $3",且小数位占2位。由于printf不自带尾随换行符,因此手动加一个换行符"澳门新萄京app,n"。

第二个程序,"%-8s"表示"$1"按字符串格式输出,但短横线"-"表示要左对齐输出,"8"表示占用8个字符宽度,不足之数在右边空格补齐。"%6.2f"表示按小数格式输出"$2 * $3",且小数位占用2位,总字符数占用6位。注意,小数点也占用一个字符宽度。因此,一个可能的输出值为"123.20"。

格式说明符"%"后可跟以下几个常见字符:

  • 格式符:
    • %d,%i:十进制整数;
    • %f:显示浮点数;
    • %s:显示字符串;
    • %u:无符号整数;
    • %%:显示%自身。
  • 修饰符:
    • N:显示宽度;N为数值,宽度不足时若为左对齐则右边空格补足,若右对齐则左边空格补足。
    • -:左对齐;
    • +:显示数值正负号。
    • 0:表示以0填充。

2.print和printf格式化输出

awk使用print和printf输出数据,不仅可以输出到标准输出中,还可以重定向到文件中,使用管道传递给另一个命令。

  1. print
    将 $0 打印到标准输出。等价于print $0
  2. print expression, expression, …
    打印各个 expression, expression 之间由 OFS 分开, 由 ORS 终止
  3. print expression,expression,… > filename
    文件名filename必须使用双引号包围,否则被当作变量。且文件只会被打开一次。
  4. print expression,expression,… >> filename
  5. print expression,expression,… | command
    将数据传递给系统命令。命令需要使用双引号包围。
  6. printf(format,expression,expression,…)
  7. printf(format,expression,expression,…) > filename
  8. printf(format,expression,expression,…) >> filename
  9. printf(format,expression,expression,…) | command
  10. close(filename), close( command)
    断开 print 与 filename (或 command) 之间的连接
  11. system(command)
    执行 command; 函数的返回值是 command 的退出状态

如果print或printf的参数列表中含有操作符,则需要使用括号包围,否则容易产生歧义。如:

print($1, $3) > ($3 > 100 ? "bigpop" : "smallpop")
print $1, ($2 > $3) 

执行系统命令的方式,可以通过管道的方式,也可以通过system()函数。注意包围命令的引号加的位置。

awk 'BEGIN{name="ma long shuai";print (1,2,3,4) | "echo " name}'
awk 'BEGIN{while (("fdisk -l" | getline) >0){print $0}}'
awk 'BEGIN{system("fdisk -l")}'
awk 'BEGIN{name="ma long shuai";system("echo " name)}'

printf命令可以输出更格式化的数据。

printf(format, value1, value2, ... , valueN)

format是一个字符串,包含按字面输出的纯文本,还包含输出格式,格式使用格式说明符"%"描述,后面跟着几个字符,这些字符控制一个value的输出格式。第一个"%"描述value1的输出格式,第二个"%"描述value2的输出格式,依次类推。因此,"%"的数量应该和被输出的value数量一样多。

例如:

{ printf("total pay for %s is $%.2fn", $1, $2 * $3) }
{ printf("%-8s $%6.2fn", $1, $2 * $3) }

第一个程序包含了两个要格式化的value,分别是"$1"和"$2 * $3"。这两个value的输出格式分别被"%s"和"%.2f"描述,前者表示按字符串格式输出"$1",后者表示按小数值格式输出"$2 * $3",且小数位占2位。由于printf不自带尾随换行符,因此手动加一个换行符"n"。

第二个程序,"%-8s"表示"$1"按字符串格式输出,但短横线"-"表示要左对齐输出,"8"表示占用8个字符宽度,不足之数在右边空格补齐。"%6.2f"表示按小数格式输出"$2 * $3",且小数位占用2位,总字符数占用6位。注意,小数点也占用一个字符宽度。因此,一个可能的输出值为"123.20"。

格式说明符"%"后可跟以下几个常见字符:

  • 格式符:
    • %d,%i:十进制整数;
    • %f:显示浮点数;
    • %s:显示字符串;
    • %u:无符号整数;
    • %%:显示%自身。
  • 修饰符:
    • N:显示宽度;N为数值,宽度不足时若为左对齐则右边空格补足,若右对齐则左边空格补足。
    • -:左对齐;
    • +:显示数值正负号。
    • 0:表示以0填充。

3.输入行的字段分隔符和行分隔符

使用"-F"选项或设置内置变量"FS"可以控制输入行的字段分隔符,默认分隔符为" "。可通过正则表达式指定分隔符,其实可以认为总是以正则方式指定分隔符。

以下是几个示例和需要注意的空格分隔符:

  1. -F " ":默认的,会压缩所有前导空白,包括制表符和空格。
  2. -F " :":当空格后跟一个冒号时作为分隔符。会压缩前导空格,但不会匹配制表符,更不会压缩制表符。
  3. -F "[ ]':只表示一个空格,不压缩任何空白。
  4. -F "|":指定竖线作为分隔符。
  5. -F ",[ t]*|[ t]+":逗号后跟0或多个空白,或者只有1或多个空白时作为分隔符。

也就是说,当空格写在最前面且不被中括号包围限制的时候,总会忽略前导空格,但不一定能匹配制表符。

使用内置变量"RS"可以控制输入行的行分隔符,默认为"n",只有遇到行分隔符时才作为"一行"记录被读取。

将其读作行分隔符不标准,应该读为"记录分隔符"。例如设置以制表符作为记录分隔符。

RS="t"

记录分隔符变量"RS"只识别第一个字符,若设置为"tt",则第二个"t"被忽略。但是控制输出记录分隔符的内置变量OFS则可识别多字符。

可通过设置FS="n";RS=""使得awk能处理多行记录。但此时,原本的每行数据整体变成一个字段。

3.输入行的字段分隔符和行分隔符

使用"-F"选项或设置内置变量"FS"可以控制输入行的字段分隔符,默认分隔符为" "。可通过正则表达式指定分隔符,其实可以认为总是以正则方式指定分隔符。

以下是几个示例和需要注意的空格分隔符:

  1. -F " ":默认的,会压缩所有前导空白,包括制表符和空格。
  2. -F " :":当空格后跟一个冒号时作为分隔符。会压缩前导空格,但不会匹配制表符,更不会压缩制表符。
  3. -F "[ ]':只表示一个空格,不压缩任何空白。
  4. -F "|":指定竖线作为分隔符。
  5. -F ",[ t]*|[ t]+":逗号后跟0或多个空白,或者只有1或多个空白时作为分隔符。

也就是说,当空格写在最前面且不被中括号包围限制的时候,总会忽略前导空格,但不一定能匹配制表符。

使用内置变量"RS"可以控制输入行的行分隔符,默认为"n",只有遇到行分隔符时才作为"一行"记录被读取。

将其读作行分隔符不标准,应该读为"记录分隔符"。例如设置以制表符作为记录分隔符。

RS="t"

记录分隔符变量"RS"只识别第一个字符,若设置为"tt",则第二个"t"被忽略。但是控制输出记录分隔符的内置变量OFS则可识别多字符。

可通过设置FS="n";RS=""使得awk能处理多行记录。但此时,原本的每行数据整体变成一个字段。

4.BGEIN和END

BEGIN和END是一个特殊的PATTERN,BEGIN引导的程序是在awk读取第一个文件第一行前要执行的awk程序,END引导的程序是在awk处理完最后一个文件最后一行后要执行的awk程序。通常BEGIN用于输出一个标题,或者初始化一些格式、变量等,END则用于最后的总结性输出。

所以awk稍微完整一点的格式为:

BGEIN{ACTIONS}PATTERN{ACTIONS}END{ACTIONS}

刨去BEGIN和END引导的两个程序,中间处理输入文件的程序PATTER{ACTIONS}称为"主输入循环(main input loop)"。在进入主输入循环之前,可以不用提供输入流,但进入主输入循环后,必须提供输入流。

例如,在开始处理文件前,设置输出报表的头部,在最后输出总共输出了多少行。其中print ""表示输出一个空行。

BEGIN{print "ID NAME GENDER GENDER";print ""}{print $0}END{print "total num: " NR}

4.BGEIN和END

BEGIN和END是一个特殊的PATTERN,BEGIN引导的程序是在awk读取第一个文件第一行前要执行的awk程序,END引导的程序是在awk处理完最后一个文件最后一行后要执行的awk程序。通常BEGIN用于输出一个标题,或者初始化一些格式、变量等,END则用于最后的总结性输出。

所以awk稍微完整一点的格式为:

BGEIN{ACTIONS}PATTERN{ACTIONS}END{ACTIONS}

刨去BEGIN和END引导的两个程序,中间处理输入文件的程序PATTER{ACTIONS}称为"主输入循环(main input loop)"。在进入主输入循环之前,可以不用提供输入流,但进入主输入循环后,必须提供输入流。

例如,在开始处理文件前,设置输出报表的头部,在最后输出总共输出了多少行。其中print ""表示输出一个空行。

BEGIN{print "ID NAME GENDER GENDER";print ""}{print $0}END{print "total num: " NR}

5.数组

awk的数组和shell的数组类似,都支持数值index的普通数组和字符串index的关联数组,其实数值index仍然会转换成字符串格式的index,所以awk的数组类型都是关联数组。

数组格式:array_name[index]
数值赋值:array_name[1]=value1
引用数组:array_name[1]

需要注意的是,关联数组的index必须使用双引号包围,例如array_name["ma"],如果写成array_name[ma],则表示使用变量"ma"的值作为index。若"ma"变量未定义,则这会定义一个新的数组array_name[""]

使用index in array_name的方式可以判断数组array_name中是否有index下标对应的数组元素。如果有,它会返回1,否则返回0。所以判断语句可以如下:

if ( "ma" in array_name )

其实,判断某个数组变量的值是否为空也可判断该数组元素是否存在,如下。但这有副作用,当该元素不存在时,会创建它。

if ( array_name["ma"] != "" )

for循环的一种变体:

for (i in array_name){
    do something about array_name[i]
}

可以用于遍历数组,其中变量"i"是遍历数组时的index,array_name是数组名。这是以遍历index的方式遍历数组。由于index的顺序随机,所以遍历时顺序也是随机的。当然,遍历数组的方式有多种,以上只是for循环遍历的一种方式。

使用delete语句可以删除数组中的元素或者删除整个数组。如下:

delete array_name["ma"]  # 删除array_name中下标为ma的元素
delete array_name        # 删除数组array_name

5.数组

awk的数组和shell的数组类似,都支持数值index的普通数组和字符串index的关联数组,其实数值index仍然会转换成字符串格式的index,所以awk的数组类型都是关联数组。

数组格式:array_name[index]
数值赋值:array_name[1]=value1
引用数组:array_name[1]

需要注意的是,关联数组的index必须使用双引号包围,例如array_name["ma"],如果写成array_name[ma],则表示使用变量"ma"的值作为index。若"ma"变量未定义,则这会定义一个新的数组array_name[""]

使用index in array_name的方式可以判断数组array_name中是否有index下标对应的数组元素。如果有,它会返回1,否则返回0。所以判断语句可以如下:

if ( "ma" in array_name )

其实,判断某个数组变量的值是否为空也可判断该数组元素是否存在,如下。但这有副作用,当该元素不存在时,会创建它。

if ( array_name["ma"] != "" )

for循环的一种变体:

for (i in array_name){
    do something about array_name[i]
}

可以用于遍历数组,其中变量"i"是遍历数组时的index,array_name是数组名。这是以遍历index的方式遍历数组。由于index的顺序随机,所以遍历时顺序也是随机的。当然,遍历数组的方式有多种,以上只是for循环遍历的一种方式。

使用delete语句可以删除数组中的元素或者删除整个数组。如下:

delete array_name["ma"]  # 删除array_name中下标为ma的元素
delete array_name        # 删除数组array_name

6.流程控制语句

在ACTION中,可以使用流程控制语句。包括但不限于:

if (expression) statements
if (expression) statements else statements
while (expression) statements
for (expression; expression; expression) statements
for (expression in array) statements
do statements while (expression)

还有几个能影响循环的动作:

break:退出循环。
continue:退出当前循环,进入下一个循环
next:读入下一行,并awk程序的顶端从头开始。这个awk程序是PATTERN{action}这部分,不包括BEGIN{action}。
exit code:直接进入END,若本就在END中,则直接退出awk。如果END中的exit没有定义code,则采用前一个exit的code。

6.流程控制语句

在ACTION中,可以使用流程控制语句。包括但不限于:

if (expression) statements
if (expression) statements else statements
while (expression) statements
for (expression; expression; expression) statements
for (expression in array) statements
do statements while (expression)

还有几个能影响循环的动作:

break:退出循环。
continue:退出当前循环,进入下一个循环
next:读入下一行,并awk程序的顶端从头开始。这个awk程序是PATTERN{action}这部分,不包括BEGIN{action}。
exit code:直接进入END,若本就在END中,则直接退出awk。如果END中的exit没有定义code,则采用前一个exit的code。

6.1 条件判断语句

if格式:

PATTERN {
  if (test_cmd){
      cmd1
      cmd2
      ...
  }
}

if-else格式为:

PATTERN {
   if (test_cmd){
      cmd1
      cmd2
      ......
      }
   else
      cmd3
}

当if或else结构中的命令只有一个,则其内可省大括号,如果超过一个,则需要使用大括号。

若采用一行书写格式,则如下:

PATTERN {if (test_cmd){cmd1;cmd2;...}else {cmd3;cmd4...}}

还有if-else if-else格式。

PATTERN {
    if (test_cmd){cmd_list1}
    else if {cmd_list2}
    else if {cmd_list3}
    else {cmd_list}
}

还支持多目操作符。

expression ? action1 : action2

其中"?"和":"还可以继续嵌套。

6.1 条件判断语句

if格式:

PATTERN {
  if (test_cmd){
      cmd1
      cmd2
      ...
  }
}

if-else格式为:

PATTERN {
   if (test_cmd){
      cmd1
      cmd2
      ......
      }
   else
      cmd3
}

当if或else结构中的命令只有一个,则其内可省大括号,如果超过一个,则需要使用大括号。

若采用一行书写格式,则如下:

PATTERN {if (test_cmd){cmd1;cmd2;...}else {cmd3;cmd4...}}

还有if-else if-else格式。

PATTERN {
    if (test_cmd){cmd_list1}
    else if {cmd_list2}
    else if {cmd_list3}
    else {cmd_list}
}

还支持多目操作符。

expression ? action1 : action2

其中"?"和":"还可以继续嵌套。

6.2 while循环

结构:

PATTERN {
  cmd1
  while (test_cmd)
      cmd
}

当cmd有多个时,使用大括号包围。

PATTERN {
    cmd1
    while (test_cmd){
        cmd2
        cmd3
        ....
    }
}

一行书写格式:

PATTERN{cmd1;while (test_cmd){cmd1;cmd2}}

6.2 while循环

结构:

PATTERN {
  cmd1
  while (test_cmd)
      cmd
}

当cmd有多个时,使用大括号包围。

PATTERN {
    cmd1
    while (test_cmd){
        cmd2
        cmd3
        ....
    }
}

一行书写格式:

PATTERN{cmd1;while (test_cmd){cmd1;cmd2}}

6.3 do循环

和while循环类似,地位和shell中的until循环一样。都是至少执行一次命令列表。

结构:

PATTERN {
    do{
        cmd1
        cmd2
    } while (test_cmd)
}

本文由澳门新萄京app发布于计算机操作系统,转载请注明出处:澳门新萄京appawk知识点总括,awk知识点全回看

关键词:

上一篇:没有了
下一篇:没有了