1. 命令格式

gawk [OPTIONS] 'program' FILES....
program:'PATTERN{ACTION}'
一条awk命令中,PATTERN和ACTION,至少存在一个才可执行;
缺少PATTERN,则对输入行内容全部执行ACTION;
缺少ACTION,则所有匹配上PATTERN的输入行都会被输出;
在awk中使用分号“;”来分割语句;

2. awk的执行过程

awk读取一行,进行模式匹配,匹配了就执行相应的动作,没有匹配就忽略,读取下一行,重复此动作.

3. 内置变量

FS:输入文件的field分隔符,默认是空白字符;
OFS:输出文件的field分隔符,默认是空白字符;
RS:输入文件record分隔符,默认是\n;
ORS:输入文件record分隔符,默认是\n;
NF:每行的field数量,{print NF}表示显示当前行的field数量,{print $NF}表示显示当前行的最后一个field;
NR:record数,对所有输入行进行统一排序;
FNR:record数,对每个文件的输入行进行分别排序;
FILENAME:输入文件的名字;
ARGC:命令行中的参数个数;
ARGV:数组,可以将当前命令行中的参数分别加入到ARGV这个数组中,从0开始;
$1、$2、$3...$n:代表当前行中对应的field

4. 常用OPTION

-F:指定输入分隔符;
-v:指定awk的变量;像FS、OSF、RS、ORS这些变量,就可以使用-v进行重新赋值;

5. 双引号的作用

定义一个变量superuser的值为root,但是打印的时候,发现打印出了一个空行,并没有实际内容
[root@centos7 ~]# awk 'BEGIN{superuser=root;print superuser}'
空行...... 这是因为只有加上了双引号才会被awk认为是字符串,否则会被认为是变量。在上面这个例子中,想要为superuser赋值的是root字符串,但是因为没有加上双引号,被awk认为root也是一个变量,但是awk中又不存在这个变量,所以最终为superuser的变量内容就是空。
所以在awk中定义变量应该是这种情况:
[root@centos7 ~]# awk 'BEGIN{superuser="root";print superuser}'
root 使用-v参数就没有上面的限制
[root@centos7 ~]# awk -v superuser=root 'BEGIN{print superuser}'
root

6. ACTION

6.1 printf命令:按照指定的FORMAT进行格式化输出;

格式化输出:printf FORMAT, item1, item2, ...
FORMAT:FORMAT是一个字符串, 它包含按字面打印的文本, 中间散布着格式说明符, 格式说明符用于说明如何打印值. 一个格式说明符是一个%, 后面跟着几个字符, 这些字符控制一个value 的输出格式. 第一个格式说明符说明item1 的输出格式, 第二个格式说明符说明item2 的输出格式, 依次类推. 于是, 格式说明符的数量应该和被打印的item 一样多; printf不会自动产生换行符,必须手动创建;

格式符

%s:显示字符串;
%i,%d:显示十进制整数;

修饰符

#[.#]:第一个#控制显示的宽度,第二个#表示小数点后的精度;
例如:%3.1f
-减号:左对齐(不加减号,默认为右对齐);
+加号:显示数值的符号;

实例

例如:使用printf打印/etc/passwd中的$1和$3
[Allen@centos7 ~]$ head /etc/passwd | awk -F: '{printf "Username: %-12sUID: %-8i\n",$1,$3}'
Username: root UID: 0
Username: bin UID: 1
Username: daemon UID: 2
Username: adm UID: 3
Username: lp UID: 4
Username: sync UID: 5
Username: shutdown UID: 6
Username: halt UID: 7
Username: mail UID: 8
Username: operator UID: 11

6.2 if-else

语法:'if(condition){statements}[else{statements}]'
使用场景:对awk取得的整行或某个字段做条件判断;

实例

例如:当$3大于等于1000时,打印$1;
[Allen@centos7 ~]$ awk -F: '{if($3>=1000) printf "%s\n",$1}' /etc/passwd
Allen
logstash 例如:当$3大于等于1000时,打印为CommonUser: $1;否则打印为Systemuser: $1;
[Allen@centos7 ~]$ awk -F: '{if($3>=1000) {printf "CommonUser: %-15s\n",$1} else {printf "SystemUser: %s\n",$1}}' /etc/passwd | head
SystemUser: root
SystemUser: bin
SystemUser: daemon
SystemUser: adm
SystemUser: lp
SystemUser: sync
SystemUser: shutdown
SystemUser: halt
SystemUser: mail
SystemUser: operator

6.3 while

语法:while(condition){statements}
使用场景:对一行内的多个字段逐一进行类似处理时使用;或对数组中的各元素逐一处理时使用;

实例

例如:以空格开头0次或多次,后跟linux16的行,以空格为分隔符,显示每行中各字段的长度;
[Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {printf "%-55s%i\n",$i,length($i); i++}}' /boot/grub2/grub.cfg
linux16 7
/vmlinuz-4.18.14-1.el7 22
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
ro 2
rhgb 4
quiet 5
linux16 7
/vmlinuz-3.10.0-693.el7.x86_64 30
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
ro 2
rhgb 4
quiet 5 例如:以空格开头0次或多次,后跟linux16的行,以空格为分隔符,只显示每行中字段的长度>=7的字段;
[Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {printf "%-55s%i\n",$i,length($i)}; i++}}' /boot/grub2/grub.cfg
linux16 7
/vmlinuz-4.18.14-1.el7 22
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
linux16 7
/vmlinuz-3.10.0-693.el7.x86_64 30
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46

6.4 for

语法:for(expr1;expr2;expr3) statement
特殊用法:for(var in arry) statements ##用于遍历数组中的元素

实例

例如:以空格开头0次或多次,后跟linux16的行,以空格为分隔符,显示每行中各字段的长度;
[Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) printf "%-55s%i\n",$i,length($i)}' /etc/grub2.cfg
linux16 7
/vmlinuz-4.18.14-1.el7 22
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
ro 2
rhgb 4
quiet 5
linux16 7
/vmlinuz-3.10.0-693.el7.x86_64 30
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
ro 2
rhgb 4
quiet 5

7. 描述awk函数示例(至少3例)

length([s]):统计s的字符数量;

sub(r,s):将当前行中最左边第一个能被r匹配的内容,替换成s;

sub(r,s,t):将t中最左边第一个能被r匹配的内容,替换成s;

gsub(r,s):将当前行中能被r匹配的内容,全部替换成s;

gsub(r,s,t ):将t中能被r匹配的内容,全部替换成s;

split(s,a):将s分割,然后分别加入到数组a中(awk命令中没有指定FS则使用默认的空格做为分隔符);

split(s,a,fs):使用fs将s分割,然后分别加入到数组a中;

sprintf(format,expr1,expr2,exprn):返回一个字符串(不打印),这个字符串按指定的format格式化expr1..exprn

genline:读取下一行,重新设定NF、NR、FNR;

实例

实例1:length函数
[root@centos7 ~]# awk 'BEGIN{superuser="root";print length(superuser)}'
4 实例2:sub和gsub函数
[root@centos7 ~]# echo "hello World" | awk '{sub("l",1);print $0}'
he1lo World
[root@centos7 ~]# echo "hello World" | awk '{sub("l",1,$1);print $0}'
he1lo World [root@centos7 ~]# echo "hello World" | awk '{gsub("l",1);print $0}'
he11o Wor1d
[root@centos7 ~]# echo "hello World" | awk '{gsub("l",1,$1);print $0}'
he11o World 实例3:split函数
数组下标从1开始
[root@centos7 ~]# awk -F/ 'BEGIN{i="China/America/Britain";split(i,countrys);for(c=1;c<=3;c++)print countrys[c]}'
China
America
Britain
[root@centos7 ~]# awk 'BEGIN{i="China/America/Britain";split(i,countrys,"/");for(c=1;c<=3;c++)print countrys[c]}'
China
America
Britain 实例4:sprintf函数
[root@centos7 ~]# awk -F: 'NR>=1&&NR<=5{x=sprintf("%-10s%-5d",$1,$3);print x}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4 实例5:getline函数
打印出从1到10之间的偶数
awk首先读取到了第一行,就是1,然后getline,就得到了1下面的第二行,就是2,因为getline之后,awk会改变对应的NF,NR,FNR和$0等内部变量,所以此时的$0的值就不再是1,而是2了,然后将它打印出来。以此类推,就可以得到下面的结果。
[Allen@centos7 ~]$ seq 10 | awk '{getline; print $0}'
2
4
6
8
10 打印出从1到10之间的奇数
因为getline在print $0之后,此时的$0仍然是第一行。然后getline,$0变成了下一行2。依次类推,就打印出了奇数行。
[Allen@centos7 ~]$ seq 10 | awk '{print $0; getline}'
1
3
5
7
9

AWK简单使用方法的更多相关文章

  1. awk 的使用方法

    awk 的使用方法 我们知道 awk 的常用变量包括: $0 当前记录(这个变量中存放着整个行的内容) $1~$n 当前记录的第 n个字段,字段间由 FS 分隔 NF 当前记录中的字段个数,就是有多少 ...

  2. MySQL笔记-最简单的方法来解决找不到mysqld.sock文件的问题

    首先,环境:ubuntu 14.04,采用apt-get的方式安装的,手动安装可能路径设置稍有区别. 1.安装MySQL后,用命令行首次启动时发现找不到Mysqld.sock文件,提示: ERROR ...

  3. mfc显示静态图片最简单的方法

    一致都是研究如何调用opencv显示动态图片,但是很多时候在显示图标的时候,都是需要显示静态图片,现在将最简单的方法总结下: 1.添加picture控件 2.添加资源,要求为bmp 3.修改属性 结果 ...

  4. ECshop设置301最快捷最简单的方法

    ECshop设置301最快捷最简单的方法 在 init.php中加入以下代码 if (strtolower($_SERVER['SERVER_NAME'])!='www.fz1688.com') { ...

  5. git 的简单使用方法

    git 的简单使用方法1. 服务器 安装完成2. ssh 中的账号创建完成3. 创建 ssh 账号,会在 ssh 的安装目录下的home 目录里面,多了用户家目录4. 进入该目录 ,创建一个新的文件夹 ...

  6. JavaScript,一个超级简单的方法判断浏览器的内核前缀

    先说明,此处的方法是说超级简单的方法,不是指代码超级少,而是用非常简单的知识点,只要懂得怎么写JavaScript的行内样式就可以判断. 大家应该还记得JavaScript行内样式怎么写吧?(看来我是 ...

  7. NET MVC1项目升级到MVC2最简单的方法

    NET MVC1项目升级到MVC2最简单的方法 把MVC1项目升级到MVC2,最简单的做法如下: 新建MVC2项目 新建一个MVC2项目,把原来MVC1的项目文件全部拷贝到新建MVC2项目目录里,依照 ...

  8. js 获取当天23点59分59秒 时间戳 (最简单的方法)

    js 获取当天23点59分59秒 时间戳 (最简单的方法) new Date(new Date(new Date().toLocaleDateString()).getTime()+24*60*60* ...

  9. [ASP.NET]更简单的方法:FormsAuthentication登录ReturnUrl使用绝对路径

    转自:http://www.cnblogs.com/dudu/p/formsauthentication-returnurl-absoluteuri.html [ASP.NET]更简单的方法:Form ...

随机推荐

  1. 美国诚实签经验——必带材料:护照,证件照,DS160确认页,面试预约确认页,+境外照片

    Step3. 准备签证材料这些材料如果准备,请一定围绕着你的DS160表格,不可说谎,但可适当修饰,辅佐它,烘托它,营造出一种——你绝无可能去不复返,绝无可能制造麻烦,绝无想占人便宜的意思,并且随时可 ...

  2. Navicat for MySQL 激活方法

    Navicat for MySQL 激活方法: 首先下载 PatchNavicat.exe ,不知道在哪儿下的可以直接拿走: 链接:https://pan.baidu.com/s/1yy4M8IDx8 ...

  3. Linux 用户管理(2)

    Linux 用户管理2 添加修改和删除用户,必须是超级管理员root账号才可以进行的操作,所以当当前账号不是超级管理员root账号时,首先要先切换为root账号. 如图,ylq为普通用户,执行添加用户 ...

  4. A brief preview of the new features introduced by OpenGL 3.3 and 4.0

    A brief preview of the new features introduced by OpenGL 3.3 and 4.0   The Khronos Group continues t ...

  5. bzoj 4424: Cf19E Fairy && codeforces 19E. Fairy【树形dp】

    参考:https://blog.csdn.net/heheda_is_an_oier/article/details/51131641 这个找奇偶环的dp1真是巧妙,感觉像tarjan一样 首先分情况 ...

  6. php生成唯一订单号的方法

    第一种 $danhao = date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT); 第二种 $danhao = date('Ym ...

  7. epoll IO多路复用(异步阻塞AIO)

    epoll的异步阻塞(AIO): 用户线程创建epoll后,其实是内核线程负责扫描 fd 列表(在网络服务器上可以是socket,socket在创建后返回的也是文件描述符),并填充事件链表.但是,并不 ...

  8. MyElipse如何添加Emmet插件

    把这个jar文件放到myeclipse2014安装目录下dropins文件夹中,然后重启myeclipse即可. 可到window-->perferences里查看,如果成功则会看到emmet选 ...

  9. MySQL的主从复制(windows)

    在我们实际的开发中,当系统业务到达一定的程度,可能数据库会到达一定的瓶颈,但实际开发中最容易到达数据库瓶颈的应该是数据库的读性能,一般的业务大多都是读多写少,我们可以通过提高读的性能来提高数据库的整体 ...

  10. SpringMVC中Controller类的方法返回String不跳转,而是将字符串显示到页面

    问题描述: 在spring中,控制层的注解一般都是使用@Controller,如果哪个请求参数需要返回数据的话,我们可以在该方法上配合@ResponseBody注解使用,这也是比较常见的方式了. 今天 ...