Linux awk命令

参考资料

  1. linux awk命令详解
  2. [初心者向け]Awkの使い方
  3. awkコマンドの使い方
  4. 阮一峰_awk 入门教程
  5. 8 个有力的 Awk 内建变量
  6. AWK 内置函数


一. 配置项

在这里插入图片描述

1.1 基本参数

  • -F:指定字段分隔符。
    awk -F',' '{ print $1 }' file 使用逗号作为分隔符。
  • -f:指定包含awk脚本的文件。
    awk -f handle.awk file 使用 handle.awk 文件中的脚本。
  • -v:定义变量并为其赋值。
    awk -v var=10 '{ print var }' file 设置变量 var 的值为 10。
  • BEGIN{}:初始化代码块,在对每一行进行处理之前,初始化代码。
    主要是引用全局变量,设置FS分隔符等。
  • //:匹配用的代码块,可以是字符串或正则表达式。
  • {}:命令代码块,多个命令之前使用;来分隔。
  • END{}: 结尾代码块,在对每一行进行处理之后再执行的代码块。
    主要是进行最终计算或输出结尾摘要信息
awk [-F|-f|-v] 'BEGIN{} // {command1; command2} END{}' ./path/filename

1.2 内置变量

内置变量英文全称说明默认值
$0整个内容
$n每行的第n个字段
FILENAME文件名“-”
RSRecord Separator行的分隔符换行符(\n)
FSField Separator字段的分隔符空格
ORSOutput Record Separator输出行的分隔符换行符(\n)
OFSOutput Field Separator输出字段的分隔符空格
NRNumber of Records正在处理的行数
NFNumber of Fields正在处理的字段数
$NF当前行最后一个字段
$(NF-1)当前行倒数第二个字段

1.3 内置函数

函数名说明
sub(regex, sub, string)字符串替换
substr(str, start, l)字符串切割
length(String)获取字符串长度
split(String, A, [Ere])字符串分割
tolower(String)转小写
toupper(String)转大写

二. 配置项示例

2.1 -F 字段分隔符

2.1.1 指定1个字段分隔符

⏹ price.txt

香蕉,100,越南
苹果,200,柬埔寨
菠萝,500,菲律宾
  • 使用,作为字段分隔符,香蕉等水果就是第一个字段,因此是$1
awk -F"," '{print $1}' ./price.txt

在这里插入图片描述

2.1.2 指定2个字段分隔符

  • -F"[,_]":中括号内部存放字段分隔符
awk -F"[,_]" '{print $3}'

在这里插入图片描述

2.1.3 $1与$3相连输出,不分隔

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

2.1.4 $1与$3使用空格分隔

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

2.1.5 $1与$3之间手动添加空格分隔

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

2.1.6 自定义输出

awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd 

2.1.7 显示每行有多少字段

awk -F: '{print NF}' /etc/passwd 

2.1.8 将每行最后一个字段打印出来

  • {print $NF}:动作语句,告诉 awk 要对每一行执行的操作。
  • $NF:这里的 $ 符号用于引用字段,NF 是 awk 中的一个内置变量,表示当前记录中的字段数。
    $NF 表示当前记录中的最后一个字段。
awk -F: '{print $NF}' /etc/passwd

2.1.9 显示只有4个字段的行

awk -F: 'NF==4 {print }' /etc/passwd

2.1.10 显示每行字段数量大于2的行

awk -F: 'NF > 2 {print $0}' /etc/passwd  

2.2 -v 定义变量

file1.txt

  • 字段之间使用 TAB 作为分隔符。
贾飞天	18
张三	16
李四	25
  • 通过 -F 显示指定字段分隔符为 TAB
  • 通过 -v 定义一个变量count,值为 10
cat file1.txt | awk -F"\t" -v count=10 '{print $1, $2 + count}'

在这里插入图片描述

2.3 // 匹配

file2.txt

2323 SEQIN mmm isuuePayId=5768awe uuid=woenoo; jmw_state=success method=paypay info=ppp
2323 SEQOUT COST=45726
2345 SEQIN mmm isuuePayId=34895ry uuid=;ljkler jmw_state=faile method=alipay info=ddd
2345 SEQOUT COST=34855

file3.txt

2323,SEQIN,mmm,isuuePayId=5768awe,uuid=woenoo;,jmw_state=success,method=paypay,info=ppp
2323,SEQOUT,uuaa=5768,COST=45726
2345,SEQIN,mmm,isuuePayId=34895ry,uuid=;ljkler,jmw_state=faile,method=alipay,info=ddd
2345,SEQOUT,COST=34855

2.3.1 行包含与不包含

⏹ 查询包含COST的行

cat file2.txt | awk '/COST/ {print $0}'

在这里插入图片描述
⏹ 查询不包含SEQOUT的行

cat file2.txt | awk '!/SEQOUT/ {print $0}'

在这里插入图片描述

2.3.2 && 行同时包含多个关键字

⏹查询同时包含isuuePayIdsuccess的行

cat file2.txt | awk '/isuuePayId/ && /success/ {print $0}'

在这里插入图片描述

2.3.3 || 行包含关键字1或关键字2

⏹查询包含isuuePayId2323的行

cat file2.txt | awk '/isuuePayId/ || /2323/ {print $0}'

在这里插入图片描述

2.3.4 ^行头与$行尾

⏹ 查询行头为2345的行

cat file2.txt | awk '/^2345/ {print $0}'

在这里插入图片描述
⏹ 查询行尾为ppp的行

cat file2.txt | awk '/ppp$/ {print $0}'

在这里插入图片描述

2.3.5 指定字段包含/不包含关键词

⏹ 查询第四个字段包含5768的行

cat file3.txt | awk -F"," '$4~/5768/ {print $0}'

在这里插入图片描述
⏹ 查询第四个字段不包含5768的行

cat file3.txt | awk -F"," '$4!~/5768/ {print $0}'

在这里插入图片描述

2.4 {} 代码块

2.4.1 IF 语句

  • 必须用在{}中,且比较内容用()包裹起来
  • if必须是小写,不是大写

⏹ 查询第4个字段包含5768的行,并且第5个字段等于uuid=woenoo;的行

cat file3.txt | awk -F"," '{if($4~/5768/ && $5=="uuid=woenoo;") print $0}'

在这里插入图片描述

2.4.2 BEGIN{},END{}代码块

file4.txt

姓名,成绩
贾飞天,100
张三,80
李四,70
王五,59
赵六,82
王七,73
  • NR>1:跳过第一行(因为第一行是标题)
  • BEGIN{}代码块里面定义变量
  • 普通{}里面进行累加
  • END{}代码块里对最终的结果进行格式化输出
  • %d:用于代表字符串变量的占位符
  • \n:换行符
  • END{print "优秀人数:" excellent, "\n","普通人数:" common, "\n", "成绩差人数:" bad}'
    如果用这种方式写的话,输出的结果虽然也能换行,但是从第二行开始左边会多一个空格。
    因为print语句在awk中默认使用空格作为字段分隔符。
cat file4.txt | awk -F"," 'BEGIN{excellent=0;common=0;bad=0} NR>1 
{
	if($2 >= 80) {excellent++} 
	else if($2 >= 60 && $2 < 80) {common ++} 
	else {bad++}
} 
END{printf "成绩优秀人数:%d\n成绩普通人数:%d\n成绩差人数:%d\n", excellent, common, bad}'

在这里插入图片描述

2.5 FS,RS

2.5.1 FS 指定字段分隔符

  • FS-F 的作用相同,都用来指定字段分隔符。
  • FS一般在BEGIN{}代码块中使用。
  • 如果需要指定多个字段分隔符的话,使用FS="[,_]"
# 指定一个分隔符
echo "贾飞天,张三,李四" | awk 'BEGIN{FS=","} {print $3}'
# 指定两个分隔符
echo "贾飞天,张三_李四" | awk 'BEGIN{FS="[,_]"} {print $3}'

在这里插入图片描述

2.5.2 RS 指定换行符

file5.txt

Alice,25
Bob,30
Charlie,22
  • printf "%s,\n"%s表示整行,整个打印语句表示给整行后加上逗号和换行符\n
  • RS=",":表示用逗号作为换行符,可以看到由于行后面也加了逗号,所以边行变列,都变为一行了。
cat file5.txt | awk '{printf "%s,\n", $0}' | awk 'BEGIN{RS=","} {print $1}'

在这里插入图片描述

2.6 OFS 输出字段分隔符

file6.txt

线程号,唯一标识,支付方式,结果
110120,uuid=1234,pay=123alipay,result=success
256754,uuid=2332,pay=344alipay,result=fail
234556,uuid=7456,pay=869paypay,result=success
  • BEGIN{FS=","}:使用,作为字段分隔符
  • NR==1 || $3~/alipay/:输入第1行或者第3个字段包含alipay的行
  • print NR, $1, (NR == 1 ? $3 : substr($3, 5, length($3) - 4))
    • print NR, $1:打印行号,第1个字段
    • NR == 1 ? $3 : substr($3, 5, length($3) - 4):若是第一行,则直接打印第3个字段
      若不是第一行,则将第3个字段从第5位开始截取到最后
  • OFS="_":输出的字段通过_来连接
cat file6.txt | awk 'BEGIN{FS=","} NR==1 || $3~/alipay/ 
{
	print NR, $1, (NR == 1 ? $3 : substr($3, 5, length($3) - 4))
}' 
OFS="_"

在这里插入图片描述

2.7 NR 行数

2.7.1 只输出奇数行

ls -l ~/uwsgi-2.0.18/core/m*.c | awk 'NR % 2 == 1 {print "第"NR"行", $0}'

在这里插入图片描述

2.7.2 只输出第三行以后的行

ls -l ~/uwsgi-2.0.18/core/m*.c | awk 'NR > 3 {print "第"NR"行", $0}'

在这里插入图片描述

2.7.3 输出每行的行号

awk '{print NR,$0}' /etc/passwd

2.7.4 依次打印行号,字段数,最后字段值,制表符,每行内容

awk -F: '{print NR, NF, $NF, "\t", $0}' /etc/passwd 

2.7.5 显示第5行

awk -F: 'NR==5{print}'  /etc/passwd  

2.7.6 显示第5行和第6行

awk -F: 'NR==5 || NR==6 {print}'  /etc/passwd 

2.7.7 不显示第一行

route -n | awk 'NR! = 1 {print}' 

三. 内置函数

3.1 gsub() 替换全部匹配到的字符串

fruit.txt

日本苹果,100,uuid=1223
中国苹果,200,uuid=3434
越南苹果,59,uuid=2898
梨,50,uuid=8976
西瓜,56,uuid=9079
  • BEGIN{FS=","}:使用,作为分隔符
  • $1~/苹果/ && $2 > 99:条件为第1个字段包含苹果,且第2个字段 > 99
  • gsub("苹果","★苹果",$1);:将苹果替换为★苹果
# 下面这两种写法相同
cat fruit.txt | awk 'BEGIN{FS=","} $1~/苹果/ && $2 > 99 {gsub("苹果","★苹果",$1); print $0}'
# ★& 中的 & 就代表匹配到的内容
cat fruit.txt | awk 'BEGIN{FS=","} $1~/苹果/ && $2 > 99 {gsub("苹果","★&",$1); print $0}'

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值