随笔 - 72,  文章 - 0,  评论 - 1,  阅读 - 22557

语法  

awk  [options] [BEGIN] {program} [END] [file]

常用命令选项
-F fs 指定描绘一行中数据字段的文件分隔符  默认为空格
-f file 指定读取程序的文件名
-v var=value 定义awk程序中使用的变量和默认值

注意:awk 程序脚本由左大括号和右大括号定义。脚本命令必须放置在两个大括号之间。由于awk命令行假定脚本是单文本字符串,所以必须将脚本包
括在单引号内。

awk程序运行优先级是:
    1)BEGIN: 在开始处理数据流之前执行,可选项
    2)program: 如何处理数据流,必选项
    3)END: 处理完数据流后执行,可选项

awk 基本用法

1.字段提取:提取一个文本中的一列数据并打印输出

   字段相关内置变量

   $0   表示整行文本

   $1   表示文本行中的第一个数据字段

   $2   表示文本行中的第二个数据字段

   $N   表示文本行中的第N个数据字段

   $NF   表示文本行中的最后一个数据字段

# awk '{print $0}' t.txt
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.

# awk '{print $1}' t.txt
1
2
3
4

# awk '{print $2}' t.txt
the
the
the
the

# awk '{print $3}' t.txt
quick
quick
quick
quick

# awk '{print $NF}' t.txt
dog.
dog.
dog.
dog.

2.如何打印某一行以及某一行中的某列呢?使用NR命令

# awk 'NR==3{print $0}' t.txt
3 the quick brown fox jumps over the lazy dog.

# awk 'NR==3{print $1}' t.txt
3
# awk 'NR==3{print $2}' t.txt
the

 

3.如果文件中的数据并不是以空格分隔的,比如passwd中的就是以:f分隔的,此时如果需要指定分隔符可以使用 -F

awk -F ":" 'NR==1{print $1,$3,$5}' /etc/passwd     #打印出passwd文件中的第一列第一行 第三行 第五行的内容
root 0 root

如果想改变上面的输出格式,可以直接修改print后面的部分

# awk -F ":" 'NR==1{print $1"-"$3"-"$5}' /etc/passwd  #在$1 $3 $5之间直接增加字符串
root-0-root

 

4.打印内存使用信息

# head -3 /proc/meminfo
MemTotal: 2035356 kB
MemFree: 1308408 kB
MemAvailable: 1472264 kB

# head -3 /proc/meminfo | awk 'NR==1{print $2}'

2035356

 

 awk 的优先级

BEGIN> print $0 >END

#awk 'BEGIN{print "youxianjizuigao"}{print $0}END{print "youxianjizuidi"}' t.txt
youxianjizuigao
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
youxianjizuidi

BEGIN不需要数据源就可以执行,但是programe 以及 END就必须有数据源才可以执行

# awk 'BEGIN{print "buxvyaoshujuyuan"}'
buxvyaoshujuyuan

 

 awk 高级用法

直接输出内存使用率,在awk工作时,直接给变量赋值,运算,从而直接结算出结果

# head -2 /proc/meminfo | awk 'NR==1{t=$2}NR==2{f=$2;print (t-f)*100/t "%"}'
31.101%

再来看下面 单引号和双引号要混用,否则可能会没有输出(因为引号会误认段落)

# awk 'BEGIN {name="shuangyinhao";print name}'
shuangyinhao
# awk 'BEGIN {name='danyinhao';print name}'

 awk数组的用法

# awk 'BEGIN{array[0]="apple";array[1]=16;print array[0],array[1]}'
apple 16

比较运算

如果比较的是字符串则按照ascii编码顺序比较,如果结果为真返回1,假返回0

# awk 'BEGIN{print "a">="b"}'     #不知为何要>= ,>会没有回显
0

逻辑判断

# seq 1 10 > num
# cat num
1
2
3
4
5
6
7
8
9
10
# awk '$1>5{print $1}' num  #大于5的信息输出
6
7
8
9
10

数学运算

# awk 'BEGIN{print 1+1}'

2

逻辑运算

# awk 'BEGIN{print 100>=99 && 100>=88}'    #奇怪的是只能>= >就报错
1

# awk 'BEGIN{print (100>98 && 100>99)}'    #再加一组括号就不报错了
1

匹配运算

精确匹配

# awk -F: '$1=="root"{print $0}' /etc/passwd     #打印第一行为root的信息
root:x:0:0:root:/root:/bin/bash

# awk -F: '$1!="root"{print $0}' /etc/passwd     #打印第一行不为root的信息

模糊匹配

# awk -F: '$1 ~ "ro"{print $0}' /etc/passwd     #第一行包含ro的都会被匹配到
root:x:0:0:root:/root:/bin/bash
chrony:x:997:995::/var/lib/chrony:/sbin/nologin

# awk -F: '$1 !~ "ro"{print $0}' /etc/passwd     #第一行不包含ro的都会被匹配到

 

awk的环境变量

 

FIELDWIDTHS 指定列的宽度

# awk 'BEGIN{FIELDWIDTHS="5 2 8"}NR==1{print $1,$2,$3}' /etc/passwd
root: x: 0:0:root
# cat /etc/passwd | grep root
root:x:0:0:root:/root:/bin/bash

FS 定义输入字段分隔符  OFS定义输出字段分隔符

# awk 'BEGIN{FS=":";OFS="-"}$1 == "root"{print $1,$3,$5}' /etc/passwd
root-0-root

 

# awk 'BEGIN{RS=""}{print $1,$2,$3}' num   #将num文本中的输入记录分隔符定义为任意,然后输入第1至第3列
1 2 3

# awk 'BEGIN{RS="";OFS="\t"}{print $1,$2,$3}' num   #将输出的资源字段分隔符定义为\t得到以下效果
1       2       3

# awk 'BEGIN{RS="";ORS="**********"}{print $1,$2,$3}' num   #将输出记录分隔符号定义为***********
1 2 3**********[root@localhost shell_16]#

 

awk的流程控制

# awk '{if($1>5)print $1}' num     #if判断
6
7
8
9
10

 

# awk '{if ($1<5)print $1*2;else print$1/2}' num
2
4
6
8
2.5
3
3.5
4
4.5
5

# awk -v 'sum=0' '{sum+=$1}END{print sum }' num     #-v定义变量  sum只能定义到外面否则循环时,每次都会归0
55

下面的例子 将每一行的数值累加

# cat num2
60 50 100
150 30 10
70 100 40

# awk '{sum=0;for (i=1;i<4;i++){sum+=$i} print sum}' num2   #使用for循环

210
190
210

# awk '{sum=0;i=1;while(i<4){sum+=$i;i++}print sum}' num2   #使用while循环
210
190
210

 

# awk '{sum=0;i=1;while(i<4){sum+=$i;if(sum>150){break}i++}print sum}' num2  #当sum>150时跳出循环
210
180
170

小技巧 

# cat t.txt
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.

# awk 'END{print NR}' t.txt     #打印文本行数
5


# awk 'END{print $0}' t.txt     #打印文本最后一行内容
5 the quick brown fox jumps over the lazy dog.


# awk 'END{print NF}' t.txt    #打印文本列数
10

posted on   wilson'blog  阅读(310)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示