Linux Shell常用技巧(四)
九. awk实用功能:
和sed一样,awk也是逐行扫描文件的,从第一行到最后一行,寻找匹配特定模板的行,并在这些行上运行“选择”动作。如果一个模板没有指定动作,这些匹配的行就被显示在屏幕上。如果一个动作没有模板,所有被动作指定的行都被处理。
1. awk的基本格式:
/> awk 'pattern' filename
/> awk '{action}' filename
/> awk 'pattern {action}' filename
具体应用方式分别见如下三个用例:
/> cat employees
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
/> awk '/Mary/' employees #打印所有包含模板Mary的行。
Mary Adams 5346 11/4/63 28765
#打印文件中的第一个字段,这个域在每一行的开始,缺省由空格或其它分隔符。
/> awk '{print $1}' employees
Tom
Mary
Sally
Billy
/> awk '/Sally/{print $1, $2}' employees #打印包含模板Sally的行的第一、第二个域字段。
Sally Chang
2. awk的格式输出:
awk中同时提供了print和printf两种打印输出的函数,其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。下面给出基本的转码序列:
转码 | 含义 |
\n | 换行 |
\r | 回车 |
\t | 制表符 |
/> date | awk '{print "Month: " $2 "\nYear: ", $6}'
Month: Oct
Year: 2011
/> awk '/Sally/{print "\t\tHave a nice day, " $1,$2 "\!"}' employees
Have a nice day, Sally Chang!
在打印数字的时候你也许想控制数字的格式,我们通常用printf来完成这个功能。awk的特殊变量OFMT也可以在使用print函数的时候,控制数字的打印格式。它的默认值是"%.6g"----小数点后面6位将被打印。
/> awk 'BEGIN { OFMT="%.2f"; print 1.2456789, 12E-2}'
1.25 0.12
现在我们介绍一下功能更为强大的printf函数,其用法和c语言中printf基本相似。下面我们给出awk中printf的格式化说明符列表:
格式化说明符 | 功能 | 示例 | 结果 |
%c | 打印单个ASCII字符。 | printf("The character is %c.\n",x) | The character is A. |
%d | 打印十进制数。 | printf("The boy is %d years old.\n",y) | The boy is 15 years old. |
%e | 打印用科学记数法表示的数。 | printf("z is %e.\n",z) | z is 2.3e+01. |
%f | 打印浮点数。 | printf("z is %f.\n",z) | z is 2.300000 |
%o | 打印八进制数。 | printf("y is %o.\n",y) | y is 17. |
%s | 打印字符串。 | printf("The name of the culprit is %s.\n",$1); | The name of the culprit is Bob Smith. |
%x | 打印十六进制数。 | printf("y is %x.\n",y) | y is f. |
注:假设列表中的变脸值为x = A, y = 15, z = 2.3, $1 = "Bob Smith"
/> echo "Linux" | awk '{printf "|%-15s|\n", $1}' # %-15s表示保留15个字符的空间,同时左对齐。
|Linux |
/> echo "Linux" | awk '{printf "|%15s|\n", $1}' # %-15s表示保留15个字符的空间,同时右对齐。
| Linux|
#%8d表示数字右对齐,保留8个字符的空间。
/> awk '{printf "The name is %-15s ID is %8d\n", $1,$3}' employees
The name is Tom ID is 4424
The name is Mary ID is 5346
The name is Sally ID is 1654
The name is Billy ID is 1683
3. awk中的记录和域:
awk中默认的记录分隔符是回车,保存在其内建变量ORS和RS中。$0变量是指整条记录。
/> awk '{print $0}' employees #这等同于print的默认行为。
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
变量NR(Number of Record),记录每条记录的编号。
/> awk '{print NR, $0}' employees
1 Tom Jones 4424 5/12/66 543354
2 Mary Adams 5346 11/4/63 28765
3 Sally Chang 1654 7/22/54 650000
4 Billy Black 1683 9/23/44 336500
变量NF(Number of Field),记录当前记录有多少域。
/> awk '{print $0,NF}' employees
Tom Jones 4424 5/12/66 543354 5
Mary Adams 5346 11/4/63 28765 5
Sally Chang 1654 7/22/54 650000 5
Billy Black 1683 9/23/44 336500 5
#根据employees生成employees2。sed的用法可以参考上一篇blog。
/> sed 's/[[:space:]]\+\([0-9]\)/:\1/g;w employees2' employees
/> cat employees
Tom Jones:4424:5/12/66:543354
Mary Adams:5346:11/4/63:28765
Sally Chang:1654:7/22/54:650000
Billy Black:1683:9/23/44:336500
/> awk -F: '/Tom Jones/{print $1,$2}' employees2 #这里-F选项后面的字符表示分隔符。
Tom Jones 4424
变量OFS(Output Field Seperator)表示输出字段间的分隔符,缺省是空格。
/> awk -F: '{OFS = "?"}; /Tom/{print $1,$2 }' employees2 #在输出时,域字段间的分隔符已经是?(问号)了
Tom Jones?4424
对于awk而言,其模式部分将控制这动作部分的输入,只有符合模式条件的记录才可以交由动作部分基础处理,而模式部分不仅可以写成正则表达式(如上面的例子),awk还支持条件表达式,如:
/> awk '$3 < 4000 {print}' employees
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
在花括号内,用分号分隔的语句称为动作。如果模式在动作前面,模式将决定什么时候发出动作。动作可以是一个语句或是一组语句。语句之间用分号分隔,也可以用换行符,如:
pattern { action statement; action statement; etc. } or
pattern {
action statement
action statement
}
模式和动作一般是捆绑在一起的。需要注意的是,动作是花括号内的语句。模式控制的动作是从第一个左花括号开始到第一个右花括号结束,如下:
/> awk '$3 < 4000 && /Sally/ {print}' employees
Sally Chang 1654 7/22/54 650000
4. 匹配操作符:
" ~ " 用来在记录或者域内匹配正则表达式。
/> awk '$1 ~ /[Bb]ill/' employees #显示所有第一个域匹配Bill或bill的行。
Billy Black 1683 9/23/44 336500
/> awk '$1 !~ /[Bb]ill/' employees #显示所有第一个域不匹配Bill或bill的行,其中!~表示不匹配的意思。
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
5. awk的基本应用实例:
/> cat testfile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
/> awk '/^north/' testfile #打印所有以north开头的行。
northwest NW Charles Main 3.0 .98 3 34
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
/> awk '/^(no|so)/' testfile #打印所有以so和no开头的行。
northwest NW Charles Main 3.0 .98 3 34
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
/> awk '$5 ~ /\.[7-9]+/' testfile #第五个域字段匹配包含.(点),后面是7-9的数字。
southwest SW Lewis Dalsass 2.7 .8 2 18
central CT Ann Stephens 5.7 .94 5 13
/> awk '$8 ~ /[0-9][0-9]$/{print $8}' testfile #第八个域以两个数字结束的打印。
34
23
18
15
17
20
13
十. awk表达式功能:
1. 比较表达式:
比较表达式匹配那些只在条件为真时才运行的行。这些表达式利用关系运算符来比较数字和字符串。见如下awk支持的条件表达式列表:
运算符 | 含义 | 例子 |
< | 小于 | x < y |
<= | 小于等于 | x <= y |
== | 等于 | x == y |
!= | 不等于 | x != y |
>= | 大于等于 | x >= y |
> | 大于 | x > y |
~ | 匹配 | x ~ /y/ |
!~ | 不匹配 | x !~ /y/ |
/> cat employees
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
/> awk '$3 == 5346' employees #打印第三个域等于5346的行。
Mary Adams 5346 11/4/63 28765
/> awk '$3 > 5000 {print $1}' employees #打印第三个域大于5000的行的第一个域字段。
Mary
/> awk '$2 ~ /Adam/' employess #打印第二个域匹配Adam的行。
Mary Adams 5346 11/4/63 28765
2. 条件表达式:
条件表达式使用两个符号--问号和冒号给表达式赋值: conditional expression1 ? expression2 : expressional3,其逻辑等同于C语言中的条件表达式。其对应的if/else语句如下:
{
if (expression1)
expression2
else
expression3
}
/> cat testfile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
/> awk 'NR <= 3 {print ($7 > 4 ? "high "$7 : "low "$7) }' testfile
low 3
high 5
low 2
3. 数学表达式:
运算可以在模式内进行,其中awk将所有的运算都视为浮点运算,见如下列表:
运算符 | 含义 | 例子 |
+ | 加 | x + y |
- | 减 | x - y |
* | 乘 | x * y |
/ | 除 | x / y |
% | 取余 | x % y |
^ | 乘方 | x ^ y |
/> awk '/southern/{print $5 + 10}' testfile #如果记录包含正则表达式southern,第五个域就加10并打印。
15.1
/> awk '/southern/{print $8 /2 }' testfile #如果记录包含正则表达式southern,第八个域除以2并打印。
7.5
4. 逻辑表达式:
见如下列表:
运算符 | 含义 | 例子 |
&& | 逻辑与 | a && b |
|| | 逻辑或 | a || b |
! | 逻辑非 | !a |
/> awk '$8 > 10 && $8 < 17' testfile #打印出第八个域的值大于10小于17的记录。
southern SO Suan Chin 5.1 .95 4 15
central CT Ann Stephens 5.7 .94 5 13
#打印第二个域等于NW,或者第一个域匹配south的行的第一、第二个域。
/> awk '$2 == "NW" || $1 ~ /south/ {print $1,$2}' testfile
northwest NW
southwest SW
southern SO
southeast SE
/> awk '!($8 > 13) {print $8}' testfile #打印第八个域字段不大于13的行的第八个域。
3
9
13
5. 范围模板:
范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现,第一个模板的下一次出现到第一个模板的下一次出现等等。如果第一个模板匹配而第二个模板没有出现,awk就显示到文件末尾的所有行。
/> awk '/^western/,/^eastern/ {print $1}' testfile #打印以western开头到eastern开头的记录的第一个域。
western WE
southwest SW
southern SO
southeast SE
eastern EA
6. 赋值符号:
#找到第三个域等于Ann的记录,然后给该域重新赋值为Christian,之后再打印输出该记录。
/> awk '$3 == "Ann" { $3 = "Christian"; print}' testfile
central CT Christian Stephens 5.7 .94 5 13
/> awk '/Ann/{$8 += 12; print $8}' testfile #找到包含Ann的记录,并将该条记录的第八个域的值+=12,最后再打印输出。
25
Linux Shell常用技巧(四)的更多相关文章
- 【shell 大系】Linux Shell常用技巧
在最近的日常工作中由于经常会和Linux服务器打交道,如Oracle性能优化.我们数据采集服务器的资源利用率监控,以及Debug服务器代码并解决其效率和稳定性等问题.因此这段时间总结的有关Linux ...
- Linux Shell常用技巧(目录)
Linux Shell常用技巧(一) http://www.cnblogs.com/stephen-liu74/archive/2011/11/10/2240461.html一. 特殊文件: /dev ...
- [转帖]拿小本本记下的Linux Shell常用技巧(一)
拿小本本记下的Linux Shell常用技巧(一) https://zhuanlan.zhihu.com/p/73361101 一. 特殊文件: /dev/null和/dev/tty Linux系统提 ...
- [转帖]Linux Shell常用技巧(五)
Linux Shell常用技巧(五) https://zhuanlan.zhihu.com/p/73451771 1. 变量:在awk中变量无须定义即可使用,变量在赋值时即已经完成了定义.变量的类型可 ...
- Linux Shell常用技巧
转载自http://www.cnblogs.com/stephen-liu74/ 一. 特殊文件: /dev/null和/dev/tty Linux系统提供了两个对Shell编程非常有用的特殊文 ...
- Linux Shell常用技巧(一) RE
一. 特殊文件: /dev/null和/dev/tty Linux系统提供了两个对Shell编程非常有用的特殊文件,/dev/null和/dev/tty.其中/dev/null将会丢掉所有写入它 ...
- Linux Shell常用技巧(一)
一. 特殊文件: /dev/null和/dev/tty Linux系统提供了两个对Shell编程非常有用的特殊文件,/dev/null和/dev/tty.其中/dev/null将会丢掉所有写入它 ...
- Linux Shell常用技巧(七)
十六. 文件查找命令find: 下面给出find命令的主要应用示例: /> ls -l #列出当前目录下所包含的测试文件 -rw-r--r--. 1 root root 48 ...
- Linux Shell常用技巧(九)
十九. 和系统运行进程相关的Shell命令: 1. 进程监控命令(ps): 要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而ps命令就是最基本同时 ...
随机推荐
- ida不错的插件记录
IDASkins 地址 https://github.com/zyantific/IDASkins 作用 ida黑色皮肤插件 IDAFuzzy 地址 https://github.com/Ga-ryo ...
- Teamviewer 手机端怎么拖动窗口,选中文字
Teamviewer 手机端怎么拖动窗口,选中文字 Teamviewer 手机端拖动窗口,选中文字和触摸板的使用方式是一样的 点两下不松开就可以拖动 点两下不松开也可以选中文字 Teamviewer ...
- Android MVP模式就是这么回事儿
MVP模式 概念就不说了,大家都懂.View层通过Persenter层相互通信,避免了View中大量的业务代码,而将其提取到Model中.其实简单的来说,就是通过接口回调,把业务分离出去.提高代码的可 ...
- 大O表示法
概念 大O表示法是和数据项的个数相关联的粗略度量算法时间复杂度的快捷方法. 常数一个无序可重复数组插入一个数据项的时间T是常数K,常数K表示一次插入所花费的时间,包含cpu.编译器等工作时间.可表示为 ...
- 如何让你的Ssh连接,更加安全?
希望你会涨姿势. First: vim /etc/ssh/sshd_config 在Port 22下面加一行,以端口1438为例,Port 1438 然后保存,重启ssh服务 systemctl re ...
- 打开struts-config.xml 报错 解决方法Could not open the editor
打开struts-config.xml 报错 解决办法Could not open the editor 错误信息:Could not open the editor: Project XXX is ...
- Django之环境搭建
安装django pip install django 安装完django之后就有了可用的管理工具django-admin.py,我们可以用它来创建我们的项目. django-admin的语法: dj ...
- ASP.NET MVC 使用Remote特性实现远程属性验证
RemoteAttribute是asp.net mvc 的一个验证特性,它位于System.Web.Mvc命名空间 下面通过例子来说明 很多系统中都有会员这个功能,会员在前台注册时,用户名不能与现有的 ...
- Tomcat 配置学习
1 server.xml <host appBase="d:/aaa"> <Context path="/smswap" reloadable ...
- Basestation函数解析(一)
---恢复内容开始--- 1._tmain _tmain()是微软操作系统(windows)提供的对unicode字符集和ANSI字符集进行自动转换用的程序入口点函数. 首先,这个_tmain() ...