Linux中的awk命令

awk,一种处理文本文件的语言,是一个强大的文本分析工具。叫 awk是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。awk对分割后的列处理,比较方便。

1. 基础语法

awk对文本进行逐行扫描并处理。awk中使用的命令也是awk自有的,而非linux中的。比如print

awk内置变量在awk命令中使用时,不需要加$|

awk命令常见的几种形式:

awk '命令' 文件名
awk '查找模式 [命令]' 文件名 
awk [-F 域分割符] '命令' 文件名 # 默认域分割符是空格

上述'命令'都要用{}括起来,查找模式不需要。

常见运算符:

运算符描述
/str/str相当于是raw的,单独用于查找模式中时表示整行中要包含str,
= += -= *= /= %= ^= **=赋值
?:C条件表达式
||逻辑或
&&逻辑与
~ 和 !~匹配正则表达式和不匹配正则表达式,例:$1 ! /regexp/
< <= > >= != ==关系运算符
空格连接
+ -加,减
* / %乘,除与求余
+ - !一元加,减和逻辑非
^ ***求幂
++ --增加或减少,作为前缀或后缀
$字段引用
in数组成员

常见符号和指令:

命令含义
$0读入的整行内容
$NN大于0,按分割符分割后的第N列内容
print打印命令,pirnt a,b,c 打印时逗号被输出分割符替代
NRawk内置变量,当前行的行号。awk内置变量在awk命令中使用时,不需要加$
FSawk内置变量,输入域的分隔符,默认为空格,指定FS=":"等同于 -F :
OFSawk内置变量,输出域的分隔符,默认为空格,print打印时各列间的分割符
>重输出,awk '{print $1 >"t2.txt" }' t.txt
#样例
> cat awk.txt
Jack 1243 1971
Mike 3123 1980
Tom 3451 1990
> awk '{print $0}' awk.txt 
Jack 1243 1971
Mike 3123 1980
Tom 3451 1990
> awk '{print NR,$1,$3}' awk.txt 
1 Jack 1971
2 Mike 1980
3 Tom 1990


> awk '$2 ~ 1243' awk.txt 
Jack 1243 1971
> awk '$2 ~ 124355' awk.txt 
> awk '$1 ~ Jack' awk.txt #Jack当做变量赋值为空,所以都匹配
Jack 1243 1971
Mike 3123 1980
Tom 3451 1990
> awk '$1 ~ "Jack"' awk.txt  # 或  awk '$1 ~ /Jack/' awk.txt
Jack 1243 1971
> awk '$2 ~ "[0-9]*"' awk.txt
Jack 1243 1971
Mike 3123 1980
Tom 3451 1990
> awk '$2 ~ /[0-9]*/' awk.txt
Jack 1243 1971
Mike 3123 1980
Tom 3451 1990
> awk '/Jack/' awk.txt 
Jack 1243 1971
> awk '/"Jack"/' awk.txt #引号也被当做匹配字符,/str/直接的str相当于是raw的
> awk '/Jack/ {print $1,$3}' awk.txt 
Jack 1971

> awk -F: '{print $1,$7}' /etc/passwd
bin /bin/bash
daemon /bin/bash
> awk '{FS=":";OFS="#";print $1,$7}' /etc/passwd
bin#/bin/bash
daemon#/bin/bash

2. BEGIN和END模块

不管位置如何,BEGIN总是先执行,END总是最后执行。

'{命令}'增加模块:
'BEGIN{...} {命令} END{...}'

awk总是数据输入驱动的,如果仅运行 awk '{命令}' 则等待键盘输入,输入一行,命令执行一次。但如果命令中有且仅有BEGIN模块时,则不需要输入驱动。

> awk 'BEGIN{ print "Good Man"}'
Good Man

3. 流程控制语句

awk具有与C语言十分类似的控制流程功能,如if/else,while, do-whiel,for循环等。

# if 控制
awk '{if($3>1980){print $0}}' awk.txt

# while
awk '{while($3>1980){print $0;exit}}' akw.txt # 打印一个就退出

4. 数学计算

内置的一些数学函数时bash没有的。

名称返回值
exp(x)e的x次幂
int(x)x的整数部分
log(x)以e为底的x的对数
rand()0到1之间的随机数
srand(x)x是rand()的种子
sqrt(x)x的平方根
atan2(y,x)
cos(x)
sin(x)
> awk 'BEGIN{print int(15.2),sqrt(6)}'
15 2.44949

5. 字符串处理

awk提供了丰富的字符串处理函数,比较常见的有

函数名作用
index(str,substr)返回子串substr在str中第一次出现的位置
substr(str,k,m)返回str中从k到m位置的子串
length(str)返回str的长度
> awk 'BEGIN{print length(15.2)}' awk 'BEGIN{print length(15.2)}' #str加不加引号都可以
4
> awk 'BEGIN{print length("15.2")}'
4

6. 调用系统bash命令

awk可以通过system函数调用bash命令或脚本。print cmd | “/bin/bash”也可调用系统命令。

注意1:如果system()括号里面的参数没有加上双引号的话,awk认为它是一个变量,它会从awk的变量里面把它们先置换为常量,然后再回传给shell。

注意2:awk是新开一个shell,无论使用system()还是print cmd | “/bin/bash”,在相应的cmdline参数送回给shell,所以要注意当前shell变量与新开shell变量问题。要想在system中还想使用,则需要在awk外部用export。

# 例1
> awk 'BEGIN{system(date)}' # date当做变量,什么也不输出
> awk 'BEGIN{system("date")}'
Mon Oct 31 22:10:51 CST 2022
# 例2
> awk 'BEGIN{system("echo abc")}'
abc
> awk 'BEGIN{v1="echo";v2="abc";system(v1" "v2)}'
abc
> awk 'BEGIN{v1="echo";v2="abc";system(v1 v2)}' # 命令行没用空格
sh: echoabc: command not found
> awk 'BEGIN{v1=echo;v2=abc;system(v1" "v2)}' # echo和abc当做变量了
> awk 'BEGIN{abc="aaa";v1=echo;v2=abc;system("echo "v1" "v2)}'
aaa


# 例3. 解密a.txt中每一行数据
> awk '{cmd="./test decrypt "$0; system(cmd)}' a.txt  > b.txt 

# print
>  awk 'BEGIN{print "echo","abc"| "/bin/bash"}'
abc
>  awk 'BEGIN{print "echo","abc",";","echo","123"| "/bin/bash"}' # 注意分割多行命令的分号用双引号括起来
abc
123


# 作用域问题
> var=12345
> export var2=12345
# 基础验证
> awk 'BEGIN{print var}'

> awk 'BEGIN{print var2}' 
   --awk命令系统中,就没有var2这样一个变量
# 注意{var}和var的区别
>  awk 'BEGIN{system("echo $var")}'

> awk 'BEGIN{system("echo ${var}")}'

> awk 'BEGIN{system("echo $var2")}' 
12345 --awk的shell系统中,var2是存在的,且不用大括号也能识别
> awk 'BEGIN{system("echo ${var2}")}'
12345
> awk 'BEGIN{print "echo","$var"| "/bin/bash"}'

> awk 'BEGIN{print "echo","${var}"| "/bin/bash"}'

> awk 'BEGIN{print "echo","${var2}"| "/bin/bash"}'
12345
> awk 'BEGIN{print "echo","$var2"| "/bin/bash"}'
12345

7. awk命令脚本

同sed,awk也是可以将所有命令写在一个脚本文件中的:

awk -f awk脚本名

若在脚本第一行加上#!/bin/awk -f,则可直接运行脚本:

awk脚本名
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值