Linux学习整理-awk
让Moncia做的大纲,写的不错,很浅显易懂
1.简介
awk是一种强大的文本处理工具,最初由Alfred Aho、Peter Weinberger和Brian Kernighan在1977年开发。它的名字是这三位作者姓氏的首字母缩写。
awk最初是为了解决Unix系统中的文本处理问题而开发的。它可以方便地从文本文件中提取数据、搜索文本、对文件进行格式化等等。awk的设计目标是提供一种简单易用、灵活性高、功能强大的文本处理语言。
awk的工作方式是按行读取文本文件,然后将每行分解成一系列字段,再根据用户指定的模式和动作来处理每个字段。awk支持多种操作,包括字符串匹配、算术运算、条件语句、循环语句等等。用户可以自定义变量、函数和脚本,以便更好地适应特定的文本处理需求。
awk已经成为Unix和Linux系统中最常用的文本处理工具之一。它可以通过命令行界面或脚本文件来使用,也可以与其他工具(如sed、grep等)组合使用。awk的强大功能和灵活性使其成为处理大型数据文件和日志文件的首选工具之一。
2.基本语法和工作原理
2.1 语法
awk options 'pattern {action}' filename
# BEGIN END 可以省略
awk options 'BEGIN {action} pattern{action} END {action}' filename
awk -f script filename
- options:可选参数,用于指定awk的一些选项和设置。
- pattern:用于指定要匹配的模式或条件。
- {action}:用于指定要执行的动作或命令。
- filename:要处理的文本文件名。
属性 options
当使用awk命令时,可以使用一些常用的选项(options)来配置awk的行为。以下是一些常用的awk选项的简单介绍:
- -F separator:指定字段分隔符。默认情况下,awk使用空格作为字段分隔符,但使用-F选项可以指定其他字符作为字段分隔符。例如,-F ,表示以逗号作为字段分隔符。
- -v var=value:定义一个变量并赋值。可以使用该选项在awk脚本中定义变量,并将其赋予指定的值。例如,-v count=10定义了一个名为count的变量,并将其值设置为10。
- -f scriptfile:从指定的脚本文件中读取awk命令。使用该选项可以将awk命令保存在一个独立的脚本文件中,并通过-f选项指定该脚本文件进行执行。
模式 pattern
在awk中,pattern用于匹配输入数据的特定行或字段。以下是一些常用的pattern:
- /pattern/:匹配包含指定模式的行。例如,/hello/将匹配包含单词“hello”的所有行。
- $n~/pattern/:匹配指定字段中包含特定模式的行。例如,$2~/hello/将匹配第二个字段中包含单词“hello”的所有行。
- ! /pattern/:匹配不包含指定模式的行。例如,! /hello/将匹配不包含单词“hello”的所有行。
- BEGIN:在读取输入文件之前执行一次。例如,BEGIN { print “Start processing” }将在读取输入文件之前输出“Start processing”。
- END:在读取输入文件之后执行一次。例如,END { print “End processing” }将在读取输入文件之后输出“End processing”。
- NR==n:匹配第n行。例如,NR==5将匹配第5行。
- NF==n:匹配包含n个字段的行。例如,NF==3将匹配包含3个字段的所有行。
这些是一些常用的awk pattern,可以根据具体需求来选择和使用。使用这些 pattern 可以帮助你更好地控制和定制awk的行为,并提取和处理输入数据中的特定信息。
2.2 工作原理
- 按行读取文本文件。
- 将每行分解成一系列字段,以空格或制表符作为默认分隔符。
- 对每个字段应用指定的模式进行匹配。
- 如果模式匹配成功,则执行指定的动作或命令。
- 重复以上步骤,直到处理完所有行。
awk的工作方式类似于一个过滤器,它可以根据用户指定的模式和动作来处理文本文件。awk中的模式可以是正则表达式、比较操作符、逻辑操作符等等,用于匹配文本中的某些内容。动作可以是打印、计算、赋值、格式化等等,用于对匹配到的内容进行处理。
awk的默认操作是打印匹配到的行,如果没有指定动作,则会自动打印整个匹配到的行。awk还支持多种选项和设置,例如自定义分隔符、输出格式、变量定义等等,以便更好地适应不同的文本处理需求。
options
是可以选的,pattern
和action
也是可选的,如果pattern
缺失的时候,对所有行,执行action
,如果action
缺失,则对pattern
筛选出来的行进行{ print }
操作。
缺失action的情况
$ awk 'NR>3' awktest
ddddd 4 ddddd,4
eeeeee 5 eeeeee,5
缺失pattern的情况
$ awk '{print $3}' awktest
aa,1
bbb,2
cccc,3
ddddd,4
eeeeee,5
3.分隔符和函数,变量
默认情况下,awk使用空格作为字段分隔符。但是你也可以自定义分隔符来处理不同格式的输入数据。
3.1 分隔符
默认空格分割的时候,总共是3列
$ awk '{print $1, $2, NF}' awktest
aa 1 3
bbb 2 3
cccc 3 3
ddddd 4 3
eeeeee 5 3
分隔符是,的时候,总共是2列
$ awk -F ',' '{print $2, NF}' awktest
1 2
2 2
3 2
4 2
5 2
3.2 变量
带有
※
的 是比较常用的内置变量
※$0
: 当前行的完整文本。
※$1, $2, ..., $NF
: 当前行的第1、2、…、最后一个字段。
ARGC
: 命令行参数的数量。
ARGIND
: 正在处理的当前文件在 ARGV 中的索引。
ARGV
: 保存命令行参数的数组。
ENVIRON
: 环境变量数组。
ERRNO
: 如果在执行 getline 进行重定向、getline 进行读取,或者 close() 过程中发生系统错误,那么 ERRNO 将包含描述该错误的字符串。该值在非英语语境下可能会被翻译。
FIELDWIDTHS
: 由空格分隔的字段宽度列表。当设置时,gawk会将输入解析为固定宽度的字段,而不是使用 FS 变量的值作为字段分隔符。参见上文中的 Fields。
FILENAME
: 当前输入文件的名称。
FNR
: 当前文件中的记录行号。它与NR
类似,但相对于当前文件。当 AWK 操作多个文件时它很有用。 FNR
的值随新文件重置。
FPAT
: 描述记录中字段内容的正则表达式。当设置时,gawk会将输入解析为字段,其中字段与正则表达式匹配,而不是使用 FS 变量的值作为字段分隔符。参见上文中的 Fields。
※FS
: 字段分隔符,默认是空格。
IGNORECASE
: 控制所有正则表达式和字符串操作的大小写敏感性。默认值0
,区分大小写。非0
的时候,忽略大小写。
※NF
: 当前输入记录中的字段数。
※NR
: 到目前为止已经看到的总输入记录数。
OFMT
: 数字的输出格式,默认为 “%.6g”。
※OFS
: 输出字段分隔符,默认为空格。
※ORS
: 输出记录分隔符,默认为换行符。
※RS
: 记录分隔符,默认是换行符。
$ awk 'BEGIN { NT=","; NS= ";" }{print NR, FNR, ARGV[0], ARGV[1], FILENAME}' awktest
1 1 awk awktest awktest
2 2 awk awktest awktest
3 3 awk awktest awktest
4 4 awk awktest awktest
5 5 awk awktest awktest
3.3 函数
内置函数
数字函数
函数 | 功能 |
---|---|
atan2(y, x) | 三角函数,返回 y/x 的反正切值,以弧度表示 。 |
sin(expr) | 三角函数, 返回 expr 的正弦值,expr 单位为弧度。 |
cos(expr) | 三角函数, 返回 expr 的余弦值,expr 单位为弧度。 |
int(expr) | 截断为整数。 |
exp(expr) | 指数函数。 |
log(expr) | 自然对数函数。 |
rand() | 返回一个介于 0 和 1 之间的随机数 N,满足 0 ≤ N < 1。 |
sqrt(expr) | 平方根函数。 |
srand([expr]) | 使用 expr 作为新的随机数生成器的种子。如果未提供 expr,则使用当前时间作为种子。返回值是随机数生成器的先前种子。 |
字符串函数
函数 | 功能 |
---|---|
index(s, t) | 返回字符串 t 在字符串 s 中的位置,如果 t 不存在则返回 0。(这意味着字符索引从 1 开始。) |
length([s]) | 返回字符串 s 的长度,如果未提供 s 则返回 $0 的长度。作为非标准扩展,当使用数组作为参数时,length() 返回数组中的元素数量。 |
strtonum(str) | 检查字符串 str 并返回其数值。如果 str 以前导零开头,strtonum() 将其视为八进制数。如果 str 以前导的 0x 或 0X 开头,strtonum() 将其视为十六进制数。否则,默认为十进制。 |
substr(s, i [, n]) | 返回字符串 s 从位置 i 开始的最多 n 个字符的子字符串。如果省略 n,则使用 s 的剩余部分。 |
tolower(str) | 返回字符串 str 的副本,其中所有大写字符被翻译为它们相应的小写字符。非字母字符保持不变。 |
toupper(str) | 返回字符串 str 的副本,其中所有小写字符被翻译为它们相应的大写字符。非字母字符保持不变。 |
正则表达式函数
函数 | 功能 |
---|---|
match(str, regexp) | 返回字符串 t 在字符串 s 中的位置,如果 t 不存在则返回 0。(这意味着字符索引从 1 开始。) |
gsub(r, s [, t]) | 在字符串 t 中全局替换匹配正则表达式 r的内容为 s。 |
sub(r, s [, t]) | 类似于 gsub(),但仅替换第一个匹配的子字符串。 |
数组函数
函数 | 功能 |
---|---|
asort(s [, d [, how] ]) | 返回源数组 s 中元素的数量。使用 gawk 的标准规则对数组 s 的内容进行排序,并用从1开始的顺序整数替换排序后的值 s 的索引。如果指定了可选的目标数组 d,则首先将 s 复制到 d,然后对 d 进行排序,保留源数组 s 的索引不变。可选的字符串 how 控制排序的方向和比较模式,它还可以是一个用户定义的比较函数的名称。 |
asorti(s [, d [, how] ]) | 返回源数组 s 中元素的数量。其行为与 asort() 相同,但是使用数组的索引进行排序,而不是数组的值。排序完成后,数组被数值索引,其值是原始索引的值。原始的值将会丢失,因此如果要保留原始值,需要提供第二个数组。可选的字符串 how 的作用与上面 asort() 中所述相同。 |
isarray(x) | 如果x是数组,就返回true,否则返回false 。 |
时间函数
函数 | 功能 |
---|---|
systime() | 返回当前时间的时间戳。 |
strftime([format [, timestamp[, utc-flag]]]) | 根据 format 中的规范格式化 timestamp。如果 utc-flag 存在且为非零或非空,则结果为 UTC,否则结果为本地时间。timestamp 应该具有与 systime() 返回的相同形式。如果省略 timestamp,则使用当前时间。如果省略 format,则使用等效于 date(1) 输出的默认格式。默认格式在 PROCINFO[“strftime”] 中可用。有关 strftime() 函数的格式转换的规范,请参阅 ANSI C 中的 strftime() 函数的规范,其中保证可用的格式转换 |
mktime(datespec) | 将 datespec 转换为与 systime() 返回的相同形式的时间戳,并返回结果。datespec 是一个字符串,格式为 YYYY MM DD HH MM SS[ DST] |
其它函数
函数 | 功能 |
---|---|
print expr-list | 打印 |
printf fmt, expr-list | 按照格式打印 |
自定义函数
自定义函数格式
function name(parameter list) { statements }
常用的statement
if (condition) statement [ else statement ]
while (condition) statement
do statement while (condition)
for (expr1; expr2; expr3) statement
for (var in array) statement
break
continue
delete array[index]
delete array
exit [ expression ]
{ statements }
switch (expression) {
case value|regex : statement
...
[ default: statement ]
}
4.使用awk提取和处理文本数据的常见用法
awk是一个强大的文本处理工具,以下是一些常见的用法,用于提取和处理文本数据:
示例文件
$ cat awktest
aa 1 aa,1
bbb 2 bbb,2
cccc 3 cccc,3
ddddd 4 ddddd,4
eeeeee 5 eeeeee,5
4.1 提取特定字段
使用print命令结合字段变量(如$1、$2)来打印指定的字段。
例如,awk '{print $1}' file.txt将提取每行的第一个字段。
$ awk '{print $1}' awktest
aa
bbb
cccc
ddddd
eeeeee
4.2 根据条件过滤行
使用模式匹配来过滤满足特定条件的行。
例如,awk '/pattern/{print}' file.txt将打印包含特定模式的行。
$ awk '/[a]+/{print}' awktest
aa 1 aa,1
4.3 进行计算和统计
使用内置变量和函数进行计算和统计操作。
例如,awk '{sum+=$2} END{print sum}' file.txt将计算第2个字段的总和并打印。
$ awk '{sum+=$2} END{print sum}' awktest
15
4.4 字段分割和重组
使用内置变量FS设置字段分隔符,并使用$n访问相应字段。
例如,awk -F ',' '{print $2, $1}' file.txt将以逗号为分隔符,打印每行的第二个字段和第一个字段。
$ awk -F ',' '{print $2, $1}' awktest
1 aa 1 aa
2 bbb 2 bbb
3 cccc 3 cccc
4 ddddd 4 ddddd
5 eeeeee 5 eeeeee
4.5 报表生成和格式化输出
使用printf命令进行格式化输出,生成报表和摘要信息。
例如,awk '{printf "%-10s %5d\n", $1, $2}' file.txt将按照指定格式输出每行的第一个字段和第二个字段。
awk '{printf "%-10s %5d\n", $1, $2}' awktest
aa 1
bbb 2
cccc 3
ddddd 4
eeeeee 5
这些是awk提取和处理文本数据的常见用法。根据具体需求,你可以结合awk的语法、模式匹配和内置功能来实现更复杂的文本处理任务。
5.awk脚本的编写和执行以及实用案例
给定一个文本文件,编写一个awk脚本,统计每个单词在文本中出现的次数,并按照出现次数从高到低排序输出
注意这里不用asort,asort排序完以后,索引会变成数字
测试用文件awkfile
#awkfile
able next
next abled
able next
将下面的脚本保存成awkscript
#awkscript
{
for (i = 1; i <= NF; i++) {
word = $i
word_count[word]++
}
}
END {
for (word in word_count) {
print word, word_count[word]
}
}
然后按照下面的命令执行
$ awk -f awkscript awkfile | sort -k2
abled 1
able 2
next 3
6. awk与其他文本处理工具的比较
确实,与其他文本处理工具(如sed和grep)相比,awk具有更强大的功能和更灵活的语法。awk是一种完整的编程语言,它提供了条件判断、循环结构、变量和函数等高级特性,使得处理和转换文本数据更加灵活和可定制。
然而,在某些场景下,其他工具可能更适合处理特定类型的文本数据。例如:
-
sed:sed是一种流编辑器,专注于对文本流进行转换和替换操作。它在处理大型文件或需要进行大规模替换的情况下效率更高。当仅需要简单的替换、删除或插入操作时,sed可能比awk更适合。
-
grep:grep是一种强大的模式匹配工具,用于在文本中查找特定模式的行。如果只需要查找包含特定模式的行而不需要对数据进行复杂的处理,grep可能是更简单和高效的选择。
-
其他工具:除了sed和grep,还有许多其他文本处理工具可根据具体需求使用。例如,cut用于提取字段,sort用于排序,uniq用于去重等。在特定场景下,这些工具可能更适合进行特定的文本处理操作。
综上所述,虽然awk在文本处理方面非常强大和灵活,但根据具体需求和场景,其他工具可能更适合处理特定类型的文本数据。根据任务的要求,选择合适的工具可以提高效率和便利性。
7. awk的优点和应用场景
awk是一种强大的文本处理工具,它具有以下优点和适用场景:
7.1 优点:
- 简洁高效:awk提供了简洁而强大的语法,可以快速处理和转换文本数据。
- 强大的模式匹配:awk支持正则表达式和模式匹配,可以轻松地筛选和操作特定模式的数据。
- 灵活性:awk提供了丰富的内置函数和操作符,使得数据处理更加灵活和可定制。
- 可移植性:awk是一个跨平台的工具,可以在各种操作系统上运行,并且几乎所有的UNIX系统都内置了awk。
7.2 应用场景:
- 数据提取和过滤:awk可以根据特定的模式提取和过滤文本数据,例如提取日志文件中的特定信息。
- 数据格式化和转换:awk可以根据需要对数据进行格式化和转换,例如将数据从一种格式转换为另一种格式。
- 数据统计和汇总:awk可以对数据进行统计和汇总,例如计算行数、列数、求和等操作。
- 报告生成:awk可以根据输入数据生成报告或摘要,例如生成表格、图表等
参考
或者在Linux中用下面的命令查询awk的帮助文档
info awk
man awk