侧边栏壁纸
Linux入门自学网博主等级

每日学一条Linux命令,终成Linux大神

  • 累计撰写 725 篇文章
  • 累计创建 143 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Linux awk命令详解:一种对文本文件进行分析、过滤、转换的处理工具

Linux awk命令介绍

awk是一种强大的文本处理工具,它可以对文本文件或标准输入进行分析和处理,按照指定的规则或模式进行匹配、过滤、替换、计算等操作,生成格式化的文本或报表。awk是由Aho, Weinberger和Kernighan三位大牛开发的,因此命名为awk。awk也是一种编程语言,它有自己的语法、变量、数组、函数等,可以编写复杂的脚本来实现各种功能。

适用的Linux版本

awk命令在大多数Linux发行版中都是默认安装的,可以通过[linux@bashcommandnotfound.cn ~]$ which awk命令来查看awk的位置。如果没有安装awk,可以通过以下命令来安装:

  • 在基于RPM的Linux系统中(如CentOS, Fedora, RedHat等),可以使用[linux@bashcommandnotfound.cn ~]$ sudo yum install gawk命令来安装。
  • 在基于Debian的Linux系统中(如Ubuntu, Debian, Mint等),可以使用[linux@bashcommandnotfound.cn ~]$ sudo apt-get install gawk命令来安装。
  • 在基于Arch的Linux系统中(如Manjaro, Arch等),可以使用[linux@bashcommandnotfound.cn ~]$ sudo pacman -S gawk命令来安装。

Linux awk命令的基本用法

awk命令的基本语法格式如下:

[linux@bashcommandnotfound.cn ~]$ awk [选项] '[条件] {动作}' [文件名]
  • 选项:可以指定一些控制awk行为的参数,如-F指定分隔符,-v指定变量,-f指定脚本文件等。
  • 条件:可以是一个正则表达式、一个关系表达式或一个逻辑表达式,用来匹配输入文本中的某些行或字段。如果省略条件,则默认对所有行执行动作。
  • 动作:可以是一些打印、赋值、计算、循环、判断等语句,用花括号括起来,用分号分隔。如果省略动作,则默认打印匹配行。
  • 文件名:可以是一个或多个文本文件的名称,也可以省略,表示从标准输入读取数据。

Linux awk命令的常用选项说明

以下是一些常用的awk选项及其说明:

选项说明
-F fs指定输入字段分隔符为fs,默认为空格或制表符
-v var=value赋值一个用户自定义变量var,并设置其值为value
-f file从file中读取awk脚本
-m[fr] val设置内存限制为val,f表示记录数,r表示记录大小
-W option指定兼容模式或警告级别,option可以是posix, gnu, traditional, old, warn, nowarn等

Linux awk命令的实例

以下是一些常见的awk命令实例:

打印/etc/passwd文件中每行的第一列和第三列

[linux@bashcommandnotfound.cn ~]$ awk -F ':' '{print $1,$3}' /etc/passwd
  • -F ':'指定输入字段分隔符为冒号
  • {print $1,$3}打印每行的第一列和第三列,以空格分隔

统计/etc/passwd文件中用户ID大于666的用户数量

[linux@bashcommandnotfound.cn ~]$ awk -F ':' '$3>666 {count++} END {print count}' /etc/passwd
  • -F ':'指定输入字段分隔符为冒号
  • $3>500匹配第三列大于666的行
  • {count++}对匹配行的计数器加一
  • END {print count}在处理完所有行后,打印计数器的值

从文本文件中提取IP地址并去重

[linux@bashcommandnotfound.cn ~]$ awk '{for(i=1;i<=NF;i++) if($i~/^[0-9.]+$/) a[$i]++} END {for(i in a) print i}' file.txt
  • {for(i=1;i<=NF;i++) if($i~/^[0-9.]+$/) a[$i]++}遍历每行的每个字段,如果字段是一个IP地址(由数字和点组成),则将其作为数组a的下标,并将其值加一,实现去重的效果
  • END {for(i in a) print i}在处理完所有行后,遍历数组a的所有下标,并打印出来

awk命令注释

使用#符号可以在awk脚本中添加注释,注释内容会被忽略。

# 这是一个注释
awk '{print $1}' file # 这也是一个注释

awk命令提取字段

使用符号可以提取每一行的字段,0表示整行,1表示第一列,2表示第二列,依此类推。也可以使用变量或表达式来表示字段编号。例如:

# 输出文件中第二列和第四列,并用逗号分隔
awk '{print $2, $4}' OFS=',' file

# 输出文件中倒数第二列和倒数第一列,并用空格分隔
awk '{print $(NF-1), $NF}' file

# 输出文件中第一列和第n列,并用冒号分隔,其中n是一个变量
awk -v n=5 '{print $1, $n}' OFS=':' file

awk中调用shell命令

使用system函数可以在awk中调用shell命令,system函数的语法是:

system(command)

其中,command是一个shell命令,可以是内置命令或外部命令。例如:

# 在awk中调用date命令,输出当前日期和时间
awk 'BEGIN {system("date")}' 

# 在awk中调用ls命令,输出当前目录下的文件列表
awk 'BEGIN {system("ls -l")}'

awk把列值传给linux命令

# 把文件中第一列的值作为参数传给ping命令,输出ping的结果
awk '{print "ping -c 1 " $1 "\n" `ping -c 1 $1`}' file

# 把文件中第二列的值作为参数传给curl命令,输出curl的结果
awk '{print "curl -s " $2 "\n" `curl -s $2`}' file

Linux awk命令的注意事项

以下是一些使用awk命令时需要注意的事项:

  • awk命令中的单引号和双引号有不同的作用,单引号用来包含整个awk脚本,双引号用来表示字符串常量。如果在awk脚本中需要使用单引号,可以用'\''来转义。
  • awk命令中的变量有两种类型,内置变量和用户自定义变量。内置变量有一些特殊的含义和用途,如NR表示当前行号,NF表示当前行的字段数,FS表示字段分隔符等。用户自定义变量可以用任意名称,但不能与内置变量或关键字重名。
  • awk命令中的数组是一种关联数组,也就是说,数组的下标可以是任意类型的值,而不仅仅是数字。数组的元素可以通过赋值语句来创建或修改,也可以通过delete语句来删除。
  • awk命令中的正则表达式可以用来匹配输入文本中的某些模式,正则表达式可以用/ /来表示,也可以用双引号来表示。正则表达式可以用在条件中,也可以用在字符串函数中,如gsub, match, split等。
  • awk命令中的流程控制语句有if, else, while, do, for, break, continue, exit等,它们的用法和C语言类似。流程控制语句可以嵌套使用,但要注意缩进和花括号的匹配。

Linux awk命令的高级技巧

以下是一些使用awk命令时的高级技巧:

技巧1:使用awk编写函数

awk命令中可以自定义函数,函数的定义格式如下:

function name(parameter-list) {
    statements
}

函数可以在awk脚本中任何位置定义,但必须在调用之前定义。函数可以返回一个值,也可以不返回。函数可以调用其他函数,也可以递归调用自己。

例如,定义一个计算阶乘的函数:

function fact(n) {
    if (n==0) return 1
    else return n*fact(n-1)
}

技巧2:使用awk处理多个文件

awk命令可以同时处理多个文件,只需要在命令行上指定多个文件名即可。awk会按照文件名的顺序依次处理每个文件中的每一行。如果需要区分不同文件中的数据,可以使用内置变量FILENAME来获取当前处理的文件名。

例如,统计每个文件中包含hello的行数:

[linux@bashcommandnotfound.cn ~]$ awk '/hello/ {count[FILENAME]++} END {for(i in count) print i, count[i]}' file1.txt file2.txt file3.txt
  • /hello/匹配包含hello的行
  • {count[FILENAME]++}将当前文件名作为数组count的下标,并将其值加一
  • END {for(i in count) print i, count[i]}在处理完所有文件后,遍历数组count的所有下标,并打印出文件名和对应的行数
0

评论区