Linux三剑客命令之awk

1. 命令介绍

awk,全称是 "Aho, Weinberger, and Kernighan",这是其三位创始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 的姓氏的首字母组合而成。 是一种强大的文本处理工具,它可以用来处理结构化的文本数据,通常用于从文件或数据流中抽取信息、转换数据格式、计算统计信息等任务

主要功能

文本处理awk 可以轻松处理包含字段的文本文件,并支持按字段分割、搜索、替换等操作。

数据抽取:可以从结构化数据中抽取特定字段或行,用于生成报告、提取关键信息等。

格式化输出awk 可以根据用户定义的格式输出数据,比如添加分隔符、对齐字段等。

数据转换:可以根据用户定义的规则对数据进行转换,比如进行数学运算、日期格式转换等。

条件处理:支持基于条件的处理,比如根据特定条件过滤数据、执行不同的操作等。

自定义函数:可以编写自定义函数来扩展 awk 的功能,以满足特定的需求。

2. 基本用法

awk [options] 'pattern { action }' file

pattern 是一个模式,用于匹配输入数据的行。

{ action } 是一个动作块,用于指定对匹配的行执行的操作。

file 是要搜索的文件名列表。如果未提供文件名,则从标准输入读取输入。

参数

-v, --assign=<变量=值>:设置一个 AWK 变量的初始值。

-b, --bignum=<字数>:设置大数的字数。

-c, --characters-as-bytes:将字符视为字节。

-C, --traditional:将 AWK 设置为传统模式。

-d, --debug:打印调试信息。

-D, --debugger:启动调试器。

-e, --exec=<程序文本>:执行 AWK 程序文本。

-E, --expression=<程序文本>:指定 AWK 表达式。

-f, --file=<脚本文件>:指定包含 AWK 脚本的文件名。

-F, --field-separator=<字段分隔符>:设置字段分隔符。

-h, --help:显示帮助信息。

-i, --lint:启用 lint 模式。

-M, --lint-old:使用旧的 lint 模式。

-N, --lint-old-internal:使用旧的内部 lint 模式。

-n, --no-optimize:禁用优化。

-r, --re-interval:支持间隔正则表达式。

-T, --sandbox:使用沙盒模式执行程序。

-V, --version:显示版本信息。

-W, --source=<程序文本>:指定 AWK 程序文本。

--use-lc-numeric:使用本地化数字格式。

pattern

BEGIN:在处理输入之前只执行一次的模式。

END:在处理输入之后只执行一次的模式。

条件表达式:可以是任何返回真或假值的表达式。如果表达式为真,则执行相应的操作。

模式1, 模式2:当同时匹配模式1和模式2时执行的操作。这相当于逻辑与。

模式1 || 模式2:当匹配模式1或模式2时执行的操作。这相当于逻辑或。

/正则表达式/:当输入行匹配指定的正则表达式时执行的操作。

模式1 && 模式2:当同时匹配模式1和模式2时执行的操作。这相当于逻辑与。

! 模式:当输入行不匹配指定的模式时执行的操作。这相当于逻辑非。

模式

NR: 当前处理的行号(Number of Record)。

FNR: 当前文件的行号(File Number of Record)。

NF: 当前行中的字段数量(Number of Fields)。

/^pattern/: 行以指定的正则表达式 pattern 开头。

/pattern/: 行中包含指定的正则表达式 pattern

$1, $2, ..., $n: 当前行的第 1, 2, ..., n 个字段。

length($0): 当前行的字符长度。

/pattern1/, /pattern2/: 从匹配 pattern1 的行到匹配 pattern2 的行之间的所有行。

!pattern: 当行不匹配指定的正则表达式 pattern 时。

(expression): 满足指定表达式的行。

action

action 允许你对匹配到的行执行各种操作,例如打印、计算、赋值、控制流程等。可以根据具体需求组合这些 action 来实现所需的功能。

{ action }:在没有指定 pattern 的情况下执行的默认操作,即对每一行都执行。

{ print }:打印当前输入行。

{ print expr }:打印表达式 expr 的值。

{ printf format, expr1, expr2, ... }:使用指定格式打印表达式的值。

{ variable = expr }:将表达式的值赋给变量。

{ action1; action2 }:按顺序执行多个操作。

{ next }:跳过当前行,继续处理下一行。

{ nextfile }:跳过当前文件,开始处理下一个文件。

{ exit }:立即退出 AWK 程序。

{ exit expr }:根据表达式的值决定是否退出 AWK 程序。

{ delete array[index] }:删除数组中指定索引的元素。

{ next }:跳过当前行,继续处理下一行。

{ nextfile }:跳过当前文件,开始处理下一个文件。

{ continue }:继续处理下一行。

{ break }:跳出当前循环。

{ close(file) }:关闭文件。

3. 示例

1. 打印文件内容:

awk '{print}' file.txt

2. 指定字段分隔符并打印特定字段

awk -F':' '{print $1, $3}' /etc/passwd

3. 计算文件中数字的总和

awk '{ sum += $1 } END {print sum}' numbers.txt

4. 查找包含特定关键词的行

awk '/keyword/' file.txt

5. 使用 BEGIN 和 END 执行初始化和收尾操作

awk 'BEGIN {print "Start processing..."} {print $0} END {print "Processing finished."}' file.txt

6. 根据条件打印特定行

awk '$3 > 50 {print $0}' data.txt

7. 在条件满足时进行操作

awk '$1 == "John" {print "Found John:", $0}' names.txt

8. 计算文件中特定列的平均值

awk '{ sum += $2; count++ } END {print "Average:", sum/count}' data.txt

9. 删除文件中的空行

awk NF file.txt

这个命令使用了 AWK 中的一个特殊的模式 - NF,它用于匹配非空字段的行。NF 是一个内置的 AWK 变量,它存储了当前行中的字段数量(即非空字段的数量)。 

对于文件 file.txt 中的每一行,如果该行包含一个或多个非空字段,则打印该行。换句话说,它会删除文件中的空行,因为在 AWK 中,空行被视为没有字段的行,所以它们不会匹配 NF 模式。 

10. 处理多个文件并打印文件名

awk '{print "File:", FILENAME, "Line:", NR, "Content:", $0}' file1.txt file2.txt

11. 计算文件中行数

awk 'END {print NR}' file.txt

12. 查找并打印文件中最长的行

awk 'length > max_length { max_length = length; longest_line = $0 } END {print longest_line}' file.txt

13. 打印文件中特定范围的行(例如,打印第 5 行到第 10 行):

awk 'NR >= 5 && NR <= 10 {print}' file.txt

14. 将文件中所有大写字母转换为小写字母

awk '{print tolower($0)}' file.txt

15. 查找文件中重复的行并打印出来:

awk '{seen[$0]++} END {for (line in seen) if (seen[line] > 1) print line}' file.txt

16. 删除文件中的重复行

awk '!seen[$0]++' file.txt

17. 按列对文件进行排序(例如,按第二列的数值大小升序排序):

awk '{print $0 | "sort -k2n"}' file.txt

18. 将文件中的制表符转换为空格

awk '{gsub(/\t/, " "); print}' file.txt

19. 统计文件中每个单词的出现次数

awk '{for(i=1; i<=NF; i++) words[$i]++} END {for(w in words) print w, words[w]}' file.txt

4. 实际应用 

统计分析日志文件

在实际工作中,AWK 可以用于各种文本处理任务,其中一个妙用是日志分析。假设你有一个 Web 服务器的访问日志文件,你可以使用 AWK 来提取有用的信息、进行统计分析、或者过滤特定的数据:

假设日志文件格式如下:

192.168.1.1 - - [10/Jan/2024:13:55:36 +0000] "GET /page1 HTTP/1.1" 200 1343
192.168.1.2 - - [10/Jan/2024:13:56:20 +0000] "GET /page2 HTTP/1.1" 404 456
192.168.1.3 - - [10/Jan/2024:13:57:05 +0000] "POST /submit HTTP/1.1" 200 765

1. 提取访问量最高的页面

awk '{print $7}' access.log | sort | uniq -c | sort -nr | head -n 1

这个命令提取了日志文件中的页面路径,然后使用 sortuniq -csort -nr 来对页面路径进行计数并按访问量降序排序,最后使用 head -n 1 获取访问量最高的页面。

sort:对 awk 输出的页面路径进行排序。

uniq -c:统计页面路径的出现次数,并输出带有计数的唯一页面路径。-c 选项会将连续的相同行统计成一行,并在行首显示该行出现的次数。

sort -nr:按照计数值(出现次数)进行降序排序, -n 表示按照数值排序, -r 表示逆序排列。

head -n 1:取排序后的结果的第一行,即访问量最高的页面路径。

2. 统计访问量最多的 IP 地址

awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 1

这个命令提取了日志文件中的 IP 地址,然后使用 sortuniq -csort -nr 来对 IP 地址进行计数并按访问量降序排序,最后使用 head -n 1 获取访问量最多的 IP 地址。

3. 计算每分钟的平均访问量

awk '{print substr($4, 14, 5)}' access.log | sort | uniq -c

这个命令提取了日志文件中的时间戳,并截取了分钟部分,然后使用 sortuniq -c 对每分钟的访问量进行统计。

处理 CSV 文件

CSV(逗号分隔值)文件是一种常见的数据格式,经常用于存储表格数据。AWK 可以帮助你对 CSV 文件进行各种操作,例如提取特定字段、计算数据、过滤行等。

假设你有一个包含以下内容的 CSV 文件 data.csv

Name,Age,City
John,30,New York
Alice,25,Los Angeles
Bob,35,Chicago

1. 提取特定字段

awk -F ',' '{print $1, $3}' data.csv

这个命令会提取 CSV 文件中的第一列和第三列,并将它们打印出来。-F ',' 选项指定字段分隔符为逗号。

2. 计算数据

awk -F ',' '{total += $2} END {print "Total Age:", total}' data.csv

这个命令会计算 CSV 文件中第二列的数据总和,并在处理完所有行后打印出来。

3. 过滤行

awk -F ',' '$2 > 25 {print $0}' data.csv

这个命令会打印出 CSV 文件中第二列大于 25 的行。

4. 添加新列

awk -F ',' '{print $0, "Gender: Male"}' data.csv

这个命令会在每一行的末尾添加一个新的列,内容为 "Gender: Male"。

文件内容处理和转换

一个实用的例子是grepsedawk 结合起来进行文件内容的处理和转换。假设你有一个文本文件 data.txt,其中包含了一些文本,你想要查找包含特定关键字的行,并且对这些行进行一些修改。

例如,假设 data.txt 的内容如下:

This is line 1.
This is line 2 with keyword1.
This is line 3 with keyword2.
This is line 4 with keyword1 and keyword2.
This is line 5.

查找包含关键字 keyword1 的行,并且在这些行的末尾添加一个新的文本:

grep 'keyword1' data.txt | sed 's/$/ - Added text/' | awk '{print $0}'

grep 'keyword1' data.txt使用 grep 查找包含关键字 keyword1 的行,并将结果输出到标准输出。

sed 's/$/ - Added text/'使用 sed 将每行的末尾($)替换为 - Added text,即在每一行的末尾添加了新文本。

awk '{print $0}'使用 awk 读取 sed 的输出,并将每行原封不动地打印出来。

最终的输出将是这些包含关键字 keyword1 的行,并且在每一行末尾添加了新文本 - Added text 的内容:

This is line 2 with keyword1. - Added text
This is line 4 with keyword1 and keyword2. - Added text
  • 42
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值