Shell -----awk

7 篇文章 0 订阅
本文详细介绍了awk命令的基本用法,包括字段变量、选项设置、运算符、BEGIN/END关键字以及内建变量的使用。通过实例展示了如何进行普通输出、格式化输出、指定分隔符、从文件读取指令、设置变量以及使用正则表达式进行内容筛选。此外,还提及了字符串函数的应用,如长度计算、大小写转换等。文章最后提供了awk在处理行数据时的实战技巧,帮助读者更好地理解和掌握awk在实际工作中的应用。
摘要由CSDN通过智能技术生成

1、简介

awk与grep、sed命令一样都是以行为单位读取文本的,默认以空格或Tab键为分隔符,将分割所得的各个字段保存到内建变量中供后续使用。

命令格式:

awk [选项] '命令' 文件名

选项说明:

  • -F fs or --field-separator fs:相当于内建变量“FS”,指定分割符为fs,默认为空格或Tab制表符;
  • -f scripfile or --file scriptfile:从文件中读取awk指令,用来代替命令行中输入的命令;
  • -v var=value or --asign var=value:设置一个变量并且附上初值。
    字段变量:
  • $0:整个文本行
  • $1:文本行中第1个数据字段
  • $2:文本行中第2个数据字段
  • $n:文本行中第n个数据字段

2、基本用法

普通输出内容:

linrm@linrm-VirtualBox:~$ cat file1.txt
i am a test file!
thank you!
r u ok?
year, month, day, hour, minute, second
linrm@linrm-VirtualBox:~$ awk '{print $1,$4}' file1.txt # 普通输出
i test
thank
r
year, hour,
linrm@linrm-VirtualBox:~$ awk '{printf "%-8s %-10s\n",$1,$4}' file1.txt # 格式化输出
i        test
thank
r
year,    hour,

指定“,”为分割符:

linrm@linrm-VirtualBox:~$ awk -F, '{print $1,$4}' file1.txt
i am a test file!
thank you!
r u ok?
year  hour

指定多个分割符输出(首先使用空格,然后在使用其他分割符):

linrm@linrm-VirtualBox:~$ awk -F '[, ]' '{print $1,$2,$4}' file1.txt
i am test
thank you!
r u
year

从文件中读取awk指令:

linrm@linrm-VirtualBox:~$ cat file.awk
{print $1,$4}
linrm@linrm-VirtualBox:~$ awk -f file.awk file1.txt
i test
thank
r
year, hour,

设置变量:

linrm@linrm-VirtualBox:~$ cat file2.txt
101 i am a test file!
102 thank you!
103 r u ok?
104 year, month, day, hour, minute, second
linrm@linrm-VirtualBox:~$ awk -va=1 -vb=sss '{print $1,$1+a,$1a,$1b}' file2.txt
101 102 1011 101sss
102 103 1021 102sss
103 104 1031 103sss
104 105 1041 104sss

3、运算符

运算符描述
= += -= *= /= %= ^= **=赋值
?:C语言三目运算符
< <= > >= != ==关系运算
+ - * / %运算
^ **求幂
++ –自增自减
ll和&&逻辑或/与
和!匹配正则表达式与否
空格连接
$字段引用
in数组成员

过滤第一列大于102的行:

linrm@linrm-VirtualBox:~$ cat file2.txt
101 i am a test file!
102 thank you!
103 r u ok?
104 year, month, day, hour, minute, second
linrm@linrm-VirtualBox:~$ awk '$1>102' file2.txt
103 r u ok?
104 year, month, day, hour, minute, second

过滤第一列大于101并且第二列等于thank的行:

linrm@linrm-VirtualBox:~$ awk '$1 > 101 && $2 == "thank" {print $1,$2,$3}' file2.txt
102 thank you!

4、BEGIN/END关键字

这两个关键字的作用是指定脚本命令的运行时机,默认情况下awk是从输入中读取一行字符串,然后对该行执行相应的命令,而有时候想在执行这些命令之前先进行一些其他的脚本命令,则可以使用BEGIN关键字,而END关键字的处理时机则刚好相反。

linrm@linrm-VirtualBox:~$ awk 'BEGIN{print "---file start---"} {print $1,$4} END{print "---file end---"}' file2.txt
---file start---
101 a
102
103 ok?
104 day,
---file end---

5、内建变量

内建变量说明
$0完整的输入记录
$1 $2 $n第1、2、n个字段
FS字段分割符
ARGC命令行参数个数
ARGV命令行参数数组
ARGIND命令行中当前文件的位置(从0开始算)
FILENAME当前文件名
IGNORECASE是否忽略大小写
ERRNO最后一个系统错误的描述
CONVFMT转换格式(默认为%.6g)
FIELDWIDTHS字符宽度列表
FNR各文件分别计数的行号
NF一条记录的字段的数目
NR已经读出的字段的数目
OFMT数字的输出格式(默认为%.6g)
OFS输出字段分隔符
ORS输出记录分隔符
RLENGTH由match函数所匹配的字符串长度
RS记录分隔符
RSTART由match函数所匹配的第一个位置
SUBSEP数组下标分隔符

输出时以“ - ”符进行分隔:

linrm@linrm-VirtualBox:~$ awk '{print $1, $2, $3}' OFS=" - " file2.txt
101 - i - am
102 - thank - you!
103 - r - u
104 - year, - month,

查看每一行的字段数:

linrm@linrm-VirtualBox:~$ awk '{print "NF = " NF}' file2.txt # 或:awk '{printf "NF = %s\n", NF}' file2.txt
NF = 6
NF = 3
NF = 4
NF = 7

忽略大小写(网上是这么写的,但我试了下好像不行,难道哪里出错了?):

linrm@linrm-VirtualBox:~$ awk 'BEGIN{IGNORECASE=1} /thank/ {print $1, $2, $3}' file2.txt

6、支持正则表达式

输出包含字符串“ou”的行:

linrm@linrm-VirtualBox:~$ awk '/ou/' file2.txt 	# 输出包含"ou"的行
102 thank you!
104 year, month, day, hour, minute, second
linrm@linrm-VirtualBox:~$ awk '!/ou/' file2.txt # 输出不包含"ou"的行
101 i am a test file!
103 r u ok?

输出第2列包含字符“i”的行的第1、2、3列:

linrm@linrm-VirtualBox:~$ awk '$2 ~ /i/ {print $1, $2, $3}' file2.txt 	# ~表示匹配正则表达式
101 i am
linrm@linrm-VirtualBox:~$ awk '$2 !~ /i/ {print $1, $2, $3}' file2.txt 	# !~表示不匹配正则表达式
102 thank you!
103 r u
104 year, month,

7、字符串函数

函数说明
length()返回字符串的长度
index()返回下标
tolower()转换成小写并返回字符串
toupper()转换成大写并返回字符串
substr()返回字符串中的子串
match()返回下标,但它不搜索子串
sub()替换匹配的第一个字符串序列,并返回整个字符串
gsub()替换匹配的所有字符串序列,并返回整个字符串
split()分割字符串并将各部分放到使用整数下标的数组中

打印各行字符串的长度:

linrm@linrm-VirtualBox:~$ awk '{print length()}' file2.txt # 这里的“()”可省略
21
14
11
42

打印字符串长度超过20的行:

linrm@linrm-VirtualBox:~$ awk 'length>20' file2.txt
101 i am a test file!
104 year, month, day, hour, minute, second

字符串大小写转换:

linrm@linrm-VirtualBox:~$ awk '{print $1, tolower($2), toupper($3)}' file2.txt
101 i AM
102 thank YOU!
103 r U
104 year, MONTH,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值