ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

awk命令

2021-09-21 13:02:45  阅读:156  来源: 互联网

标签:命令 awk print world root hello localhost


文本处理三剑客之awk---列编辑器

awk语法

1、hello world

\\ 将This line of data is ingored写到test里面去
[root@localhost ~]# echo 'This line of data is ingored' > test
[root@localhost ~]# cat test
This line of data is ingored
\\ 不管是用awk后面跟test文件打印hello world,还是awk后面跟任意文件一个打印。语法上要打印的hello world跟文件里面的内容没关系,只不过打印的动作会因文件内容里面的行数变化而变化。
[root@localhost ~]# awk '{print "hello world"}' test
hello world
[root@localhost ~]# awk '{print "hello world"}' wjj
hello world
hello world
hello world
hello world
hello world
hello world
hello world
\\ 如果后面不跟文件的话就会卡住,然后输入任何东西(包含空格+回车、回车)都会打印hello world,
[root@localhost ~]# awk '{print "hello world"}'
q
hello world
t
hello world
y
hello world
u
hello world

hello world

\\ 文件里面明明有多行,但是只打印一行(用echo命令echo一个空行出来,空行也可以是处理对象,空行是一行,)
[root@localhost ~]# echo|awk '{print "hello world"}'
hello world
[root@localhost ~]# echo

\\ 在print语句中不加任何参数,就会打印出文件中的内容
[root@localhost ~]# awk '{print}' test
This line of data is ingored
\\ 在print后面加上$0还是打印整行(因为This就是$1,line是$2,of是$3,data是$4,is是$5,ingored是$6,在awk里面$0表示匹配awk整行文本的内容 )
[root@localhost ~]# awk '{print $0}' test
This line of data is ingored

awk分为三部分:BEGIN{}+{正文}+END{}
awk ‘BEGIN{i=1}{print “hello world”}END{print i}’ //i是变量,在awk里面,变量是不需要$符号的,直接用变量的一致去调用就可以了

// 用awk生成一个表格(如果想打印表格,就必须把表格保存在文本里面,才能打印)
[root@localhost ~]# awk 'BEGIN{print "姓名\t\t年龄\ntom\t\t10\njerry\t\t20\nzhangsan\t15\nlisi\t\t18"}'
姓名            年龄
tom             10
jerry           20
zhangsan        15
lisi            18
// 用awk统计年龄的总和
[root@localhost ~]# awk 'NR!=1{print $2}' abc
10
20
15
18

2、模式匹配

当awk读入一行时,它试图匹配脚本中的每个模式匹配规则。只有与一个特定的模式相匹配的输入行才能成为操作对象。如果没有指定操作,与模式相匹配的输入行将被打印出来(执行打印语句是一个默认操作)。

[root@localhost ~]# cat wjj
This line of data is ingored
[root@localhost ~]# echo '' >> wjj
[root@localhost ~]# echo '' >> wjj
[root@localhost ~]# cat wjj
This line of data is ingored


[root@localhost ~]# awk '/^$/{print "This is a blank line."}' wjj        //用awk对wjj进行处理,只有匹配到空行,打印This is a blank line.不是空行的就会被打印,因为没被匹配到。(意思就是有几个空行,它就会打印几句This is a blank line.)
This is a blank line.
This is a blank line.

//既打印空行又打印不是空行的内容
[root@localhost ~]# cat wjj
This line of data is ingored
[root@localhost ~]# awk 'BEGIN{print $0}/^$/{print "This is a blank line."}' wjj
                         //之前有内容的一行已经空了,因为之前打印了This is a blank line.,而且正文里面也没用说对这一行去做处理
This is a blank line.
This is a blank line.

测试一下脚本是整数、字符串还是空行类的

[root@localhost ~]# cat awkscr 
/[0-9]+/{print "这是一个数字"}
/[a-zA-Z]+/{print "这是一个字符串"}
/^$/{print "这是一个空行"}

总的思想是,如果一个输入行能够和任何一个模式匹配,那么就执行相关的print语句。元字符+是正则表达式元字符扩展急中的一部分,他表示“一个或更多”。因此,包含一个或多个数字序列的行将被看做是一个整数。

[root@localhost ~]# awk -f awkscr 
1
这是一个数字
d
这是一个字符串

这是一个空行
ctrl+d(退出)

3、程序脚本的注释

在写脚本时添加注释是一个好的习惯。注释以字符“#”开始,以换行符结束。和sed不同,awk允许在程序的任何地方添加注释。

注意:如果以命令行的方式提供awk程序,而不是将它写入一个文件中,那么在程序的任何地方都不能用单引号,否则shell将对它进行解释而导致错误.

shell脚本第一行是:#!/bin/bash
awk脚本第一行是:#!/usr/bin/awk

4、记录和字段

awk假设它的输入是有结构的,而不只是一串无规则的字符。在最简单的情况下,它将每个输入行作为一条记录,而将由空格或制表符(tab)分隔的单词作为字段(用来分隔字段的字符被称为分隔符,默认的分隔符就是空格,并且不管有多少个空格,它都会给合并成一个)。

[root@localhost ~]# cat test
John Robinson 666-555-1111

连续的两个或多个空格和/或制表符被作为一个分隔符

字段和引用的分离

awk允许使用字段操作符$来指定字段。在该操作符后面跟着一个数字或变量,用于标识字段的位置。“$1”表示第一个字段,“$2”表示第二个字段等等。“$0”表示整个输入记录。

[root@localhost ~]# awk '{print $2,$1,$3}' test
Robinson John 666-555-1111

// 用任何计算值为整数的表达式来表示一个字段,而不只是用数字和变量。用来做运算
[root@localhost ~]# echo "a b c d"|awk 'BEGIN{one=1;two=2}{print $(one+two)}'
c

// 可以在命令行中使用-F选项改变字段的分隔符。它后面跟着(或者紧跟,或者有空白)分隔符。

//用冒号做的分隔符
[root@localhost ~]# cat passwd 
root:x:0:0:root:/root:/bin/bash     
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]# awk -F':' '{print $1,$7}' passwd    // ':'意思是以冒号作为分隔符; \t是表示一个实际的制表符的转义序列,它由单引号或双引号包围着
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
[root@localhost ~]# awk -F'x:' '{print $1}' passwd    // 以x:作为分隔符,x:前面的就是$1,x:后面就是$2
root:
bin:
daemon:

// 用数字做分隔符
[root@localhost ~]# awk -F'[0-9]+' '{print $1}' passwd
root:x:
bin:x:
daemon:x:
[root@localhost ~]# awk -F'[0-9]+' '{print $2}' passwd
:
:
:

//取本机的IP地址
[root@localhost ~]# ip a|grep 'inet '|grep -v '127.0.0.1'|awk -F'[ /]+' '{print $3}'     // 这里是把/和空格作为分隔符   
192.168.47.129

在脚本中指定域分隔符是一个好习惯并且非常方便。可以通过定义系统变量FS来改变字段风额度。因为这个必须在读取第一个输入行之前执行,所以必须在由BEGIN规则控制的操作中指定这个变量。FS默认值是空格
awk语句必须是外单内双,不然就执行不了

// 设置处理用逗号做分隔符。处理的时候是用冒号做的分隔符,输出的时候没有指定,所以它是用默认的(空格)
[root@localhost ~]# awk 'BEGIN{FS=":"}{print $1,$7}' passwd 
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin

// 设置输出用-分隔符,但是$1跟$7之间必须要加上逗号,不然就不会发生改变
[root@localhost ~]# awk 'BEGIN{FS=":";OFS="-"}{print $1,$7}' passwd 
root-/bin/bash
bin-/sbin/nologin
daemon-/sbin/nologin

// 字母“MA”,我们可以测试匹配指定的字段。使用(~)操作符可以测试一个字段的正则表达式,~是匹配,!~是不匹配
[root@localhost ~]# cat test
707-724-0000
(707) 724-0000
(707)724-0000
1-707-724-0000
1 707-724-0000
1(707)724-0000
[root@localhost ~]# awk '/1?[- ]?\(?[0-9]+\)?[- ]?[0-9]+-[0-9]+/' test  
707-724-0000
(707) 724-0000
(707)724-0000
1-707-724-0000
1 707-724-0000
1(707)724-0000

// 写一个只匹配(707) 724-0000、(707)724-0000这两行文本的表达式
[root@localhost ~]# awk '/^\([0-9]+\) ?[0-9]+-[0-9]+/' test   //^表示开头,([0-9]+都有所以不用加?,后面空格两句里面有的有有的没有所以空格后面要加?
(707) 724-0000
(707)724-0000

表达式

可以使用表达式来存储、操作和检索数据,这些操作与sed中的有很大的区别,但这是大多数程序设计语言所具有的共同特性。

一个表达式通过计算返回一个值。表达式由数字和字符串常量、变量、操作符、函数和正则表达式组成。

常量有两种类型:字符串型或数字型(“red”或1)。字符串在表达式中必须用引号括起来。

常用的转义序列:
\n 换行符
\t 水平制表符

变量是引用值的标识符。定义变量只需要为它定义一个名字并将数据赋给它即.可。变量名只能由字母、数字和下划线组成。而且不能以数字开头。变量名的大小写很重要: Salary 和salary是两个不同的变量,变量不必进行说明,你不必告诉awk什么类型的数据存储在一个变量中。每个变量有一个字符串型值和数字型值,awk能够根据表达式的前后关系来选择合适的值(不包含数字的字符串值为0)。变量不必初始化。awk 自动将它们初始化为空字符串,如果作为数字,它的值为0.
下面的表达式表示将一个值赋给x:
x=1
x是变量的名字,=是一个赋值操作符,1是一个数字常量
下面的表达式表示将字符串“hello”赋给z:
z=“hello”
空格是字符串连接操作符,表达式:
z=“hello” “world”
算术操作符

操作符描述
+
-
*
/
%取模
^取幂
**取幂
[root@localhost ~]# awk 'BEGIN{y=x+1;print y}'   //在awk里面,那个变量在使用之前没有定义它的值得话,那么它的值就是0
1

赋值操作符

操作符定义
++变量 加1
变量减1
+=将加的结果赋给变量
-+将减的结果赋给变量
*=将乘的结果赋给变量
/=将除的结果赋给变量
%=将取模的结果赋给变量
^=将取幂的结果赋给变量
**=将取幂的结果赋给变量
// 计算一个文件中空行的目录
[root@localhost ~]# cat test
707-724-0000
(707) 724-0000
(707)724-0000
1-707-724-0000
1 707-724-0000
1(707)724-0000






[root@localhost ~]# awk '/^$/{print x +=1}' test   // 匹配第一个空行的时候加1,第2个的时候加1........以此类推
1
2
3
4
5
6

“++”是递增操作符(“-”是递减操作符)。表达式每计算一次变量的值就增加1。递增和递减操作符可以出现在操作数的任何一遍,与前缀或后缀操作符一样。位置不同可以得到不同的计算结果。
++i 在返回结果前递增x的值(前缀)
i++ 在返回结果后递增x的值(后缀)

[root@localhost ~]# awk '/^$/{print i++}' test   // 先自己得到结果后再去加
0
1
2
3
4
5
[root@localhost ~]# awk '/^$/{print ++i}' test    // 在得到结果之前先运算
1
2
3
4
5
6

[root@localhost ~]# awk '/^$/{++i}END{print i}' test    // END一定是在正文执行完成之后再去做的
6

计算平均成绩

[root@localhost ~]# cat test
john 85 92 78 94 88
andrea 89 90 75 90 86
jasper 84 88 80 92 84

// 先求出这三个人五门成绩的总分跟平均值
[root@localhost ~]# awk '{total=$2+$3+$4+$5+$6;print total}' test
437
430
428
[root@localhost ~]# awk '{total=$2+$3+$4+$5+$6;print total/5}' test
87.4
86
85.6

// 求5门成绩的平均值
[root@localhost ~]# awk '{total=$2+$3+$4+$5+$6;avg=total/5;print $1,avg}' test
john 87.4
andrea 86
jasper 85.6

系统变量

awk中有许多系统变量或内置变量。awk有两种类型的系统变量。第一种类型定义的变量默认值可以改变,例如默认的字段和记录分隔符。第二种类型定义的变量的值可用于报告或数据处理中。例如当前记录中字段的数量,当前记录的数量等。这些可以由awk自动更新,例如,当前记录的编号和输入文件名。

有一组默认值会影响对记录和字段的输入和输出的识别。系统变量FS定义字段分隔符。它的默认值为一个空格,这将提示awk可以用若千个空格和/或制表符来分隔字段。FS可以被设置为任何单独的字符或一个正则表达式,前面,我们将分隔符改变为逗号,为的是读取-一个名字和地址的列表。和FS等效的输出是0FS,它的默认值为一个空格。

NR:行号

[root@localhost ~]# awk '{print NR".",$1}' test
1. john
2. andrea
3. jasper

商品脚本(NR)

[root@localhost ~]# cat abc 
百事可乐  3
冰红茶  3
旺仔  5
农夫山泉矿泉水  2
[root@localhost ~]# cat test.sh 
#!/bin/bash

echo "商品列表:"
awk '{print NR".",$1,$2"元"}' abc

read -p "请输入要买的商品编号:" choice
read -p "请输入要买的数量:" num
awk -vcount=$num -vline=$choice 'NR==line{print "您一共买了"count"瓶"$1,"共消费"$2*count"元。"}' abc
[root@localhost ~]# bash test.sh 
商品列表:
1. 百事可乐 3元
2. 冰红茶 3元
3. 旺仔 5元
4. 农夫山泉矿泉水 2元
请输入要买的商品编号:3
请输入要买的数量:4
您一共买了4瓶旺仔 共消费20元。

处理多行记录

假设相同的数据保存在块格式的文件中。不是将所有的信息放置在一行,而是将任命放在一行,在下一行放置公司名、以此类推。

为了处理这种包括多行数据的记录,我们可以将字段分隔符定义为换行符,换行符用“\n”来表示,并将记录分隔符设置为空字符串,它代表一个空行。

[root@localhost ~]# awk '{print $1}' abc
百事可乐
冰红茶
旺仔
农夫山泉矿泉水
[root@localhost ~]# awk '{print $1$2}' abc     //用什么东西做分隔符什么东西就会消失
百事可乐3
冰红茶3
旺仔5
农夫山泉矿泉水2

[root@localhost ~]# awk 'BEGIN{FS="\n";RS=""}{print $1}' abc    // F表示字段,FS表示字段的分隔符,必须要为空,不然就乱了;R表示行,RS表示行的分隔符,行做分隔符就用\n
百事可乐  3

关系操作符和布尔操作符

操作符描述
<小于
>大于
<=小于或等于
>=大于或等于
==相等
!=不相等的
~匹配
!~不匹配

NF表示最后一列

标签:命令,awk,print,world,root,hello,localhost
来源: https://blog.csdn.net/m0_46289146/article/details/120394939

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有