这篇文章上次修改于 410 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
介绍
- 是一种强大的文本处理工具,通常用于从文本文件或数据流中提取和处理数据
语法
awk 'pattern { action }' [file]
- pattern:用于指定需要匹配的条件,可以是文本字符串或正则表达式。
- { action }:在匹配到指定 pattern 的行上执行的动作。
- file:要处理的输入文件名, 不制定文件则使用标准输入
参数
参数 | 说明 |
---|---|
-F<分隔符> 或 --field-separator=<分隔符> |
指定字段分隔符。默认是空格。 |
-f <脚本文件> 或 --file=<脚本文件> |
从指定的脚本文件中读取 awk 脚本。 |
-v <变量名>=<值> |
在 awk 脚本中设置变量的值。 |
-W <关键字> 或 --word-seq=<关键字> |
指定字符串字段的分隔符。 |
-w 或 --posix |
使用 POSIX 兼容模式。 |
-M 或 --bignum |
启用大数运算模式。 |
-b 或 --characters-as-bytes |
将字符视为字节。 |
-c 或 --traditional |
使用传统 awk 语法。 |
-C 或 --copyright |
打印版权信息。 |
-d 或 --debug |
打印调试信息。 |
-D <选项> 或 --gen-pot=<选项> |
生成 Gettext 模板。 |
-e <脚本> 或 --source=<脚本> |
直接在命令行中指定 awk 脚本。 |
-E <命令> 或 --re-interval=<命令> |
启用扩展的正则表达式语法。 |
-g 或 --gen-gettext |
生成 Gettext 目录。 |
-h 或 --help |
打印帮助信息。 |
-l <库> 或 --use-lc-numeric=<库> |
使用指定的本地化库。 |
-L 或 --lint |
启用 awk 脚本的语法检查。 |
-n 或 --non-decimal-data |
允许八进制和十六进制的数值。 |
-N 或 --use-lc-numeric |
使用本地化库。 |
-o <文件> 或 --pretty-print=<文件> |
将输出格式化并写入文件。 |
-O <级别> 或 --optimize=<级别> |
设置优化级别。 |
-p 或 --profile |
启用性能分析。 |
-P <路径> 或 --dump-variables=<路径> |
将变量信息写入指定路径的文件。 |
-r 或 --re-interval |
启用扩展的正则表达式语法。 |
-s 或 --no-optimize |
禁用所有优化。 |
-S 或 --sandbox |
启用沙盒模式。 |
-t 或 --traditional |
使用传统 awk 语法。 |
-V 或 --version |
打印版本信息。 |
请注意,awk
的不同版本可能具有不同的参数和功能。上述列表中列举的是一些常见的参数,您可以通过在终端中运行 man awk
命令来查看特定版本的 awk
的完整文档。
内置变量
内置变量 | 说明 |
---|---|
$0 |
匹配整个输入记录。 |
$1, $2, ... |
匹配输入记录中的第一个、第二个字段,依此类推。 |
NF |
包含当前记录的字段数。 |
NR |
包含当前记录的相对行号。 |
FNR |
包含当前记录的相对行号(针对当前文件)。 |
FILENAME |
包含当前输入文件的名称。 |
FS |
包含字段分隔符,默认为一个空格。 |
OFS |
输出字段分隔符,默认为一个空格。 |
RS |
输入记录分隔符,默认为换行符。 |
ORS |
输出记录分隔符,默认为换行符。 |
ARGC |
包含命令行参数的数量。 |
ARGV |
包含命令行参数的数组。 |
ENVIRON |
包含系统环境变量的数组。 |
IGNORECASE |
如果设置为非零值,则字符串比较不区分大小写。 |
CONVFMT |
控制数字转换为字符串的格式。 |
OFMT |
控制数字输出的格式。 |
RSTART |
匹配函数(如 match() )设置的字符串的起始位置。 |
RLENGTH |
匹配函数(如 match() )设置的匹配字符串的长度。 |
执行流程
- BEGIN{} : 最开始执行
- // : 正则
- {} : 循环体
- END{} : 最后执行
awk中的函数
print : 打印
printf : 格式化打印
%s : 字符串
%d : 数字
- : 左对齐
+ : 右对齐
15 : 至少占用15字符
比较表达式
> : 小于
< : 大于
>= : 小于等于
<= : 大于等于
~ : 正则匹配(包含)
!~ : 正则匹配(不包含)
逻辑表达式
&& : 逻辑与
|| : 逻辑或
! : 逻辑非
算术表达式
+ :加
- :减
* :乘
/ :除
% :求余
流程控制
- 流程控制只存在循环之中
if 使用格式:
if(){} : 单分支
if(){}else{} : 双分支
if(){}else if(){}else{} : 多分支
for循环使用格式:
for(i="初始值":条件判断:游标){}
while循环格式
while(条件判断){}
列子
- 获取/etc/password 文件的第一行到第三号,取行号,第一列,倒数第二列和最后一列
# 使用 —F 制定文件列的分割符 NR==1,NR==3 指定1到3行,使用BEGIN和END增加头尾
[root@236]# awk -F ":" 'BEGIN{print "获取passwd文件部分数据"}NR==1,NR==3{print NR,$1,$(NF-1),$NF}END{printf "%s\n", "数据获取结束"}' /etc/passwd
获取passwd文件部分数据
1 root /root /bin/bash
2 bin /bin /sbin/nologin
3 daemon /sbin /sbin/nologin
数据获取结束
- 使用| 作为输出分割符
[root@236]# awk -F: 'BEGIN{OFS=" | "}BEGIN{printf "|%+10s|%-15s|\n", "用户解释器","用户名"}NR==1,NR==5{printf "|%+15s|%-15s|\n", $NF, $1}' /etc/passwd
| 用户解释器|用户名 |
| /bin/bash|root |
| /sbin/nologin|bin |
| /sbin/nologin|daemon |
| /sbin/nologin|adm |
| /sbin/nologin|lp |
- 使用正则表达式定位
[root@AY140330180959236303Z ~]# awk -F ":" '/^root/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
- 比较表达式
# 要求打印属组ID大于属主ID的行
[root@236]# awk -F: '$4 > $3{print $0}' /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
# 打印结尾包含bash字符串的行
# $NF ~ /bash/ :尾部最后一列 包含 bash 的行
# ~ : 包含
[root@236]# awk -F: '$NF ~ /bash/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
- 逻辑表达式
# && 逻辑测试 所有条件必须满足
[root@236]# awk -F: '$3 + $4 > 500 && $3 * $4 > 500{print $0}' /etc/passwd
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
# || 逻辑测试 , 有一个条件是真
[root@236]# awk -F: '$3 + $4 > 2000 || $3 * $4 > 2000{print $0}' /etc/passwd
nobody:x:99:99:Nobody:/:/sbin/nologin
# ! 逻辑测试 条件取反
[root@AY140330180959236303Z ~]# awk -F: '!($3 + $4 > 2){print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
- 算术加运算
[root@236]# awk -F: '$3 + $4 > 1009{print $0}' /etc/passwd
- 条件控制和循环
# if条件判断
[root@236]# awk -F: 'NR==1,NR==5{if($3>$4){print "大于"}else{print "小于或等于"}}' /etc/passwd
小于或等于
小于或等于
小于或等于
小于或等于
小于或等于
# for 循环
# 第一行循环打印三次
[root@236]# awk -F: 'NR==1{for(p=0;p<3;p++){print $0}}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
# while 循环
[root@236]# awk -F: 'NR==1{p=0; while(p<2){p++; print $0}}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
[root@236]# awk -F: 'NR==1{p=0; while(p<3){print $0,p++}}' /etc/passwd
root:x:0:0:root:/root:/bin/bash 0
root:x:0:0:root:/root:/bin/bash 1
root:x:0:0:root:/root:/bin/bash 2
- 每隔5行,打印一行横线
awk -F: '{if(NR%5==0){print "----------"}print $0}' /etc/passwd
没有评论
博主关闭了评论...