0

0

awk命令详解

高洛峰

高洛峰

发布时间:2016-12-15 11:06:38

|

1896人浏览过

|

来源于php中文网

原创

一、前言

awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk。awk语言的最基本功能是在文件或字符串中基于指定规则来分解抽取信息,也可以基于指定的规则来输出数据。完整的awk脚本通常用来格式化文本文件中的信息。

二、基本语法

awk [opion] 'awk_script' input_file1 [input_file2 ...]

awk的常用选项option有:

① -F fs : 使用fs作为输入记录的字段分隔符,如果省略该选项,awk使用环境变量IFS的值

② -f filename : 从文件filename中读取awk_script

③ -v var=value : 为awk_script设置变量

awk有三种运行方式:

第一种,把awk的脚本命令直接放在命令中。

第二种,把awk的所有的脚本命令放在一个脚本文件中,然后用-f选项来指定要运行的脚本命令文件。

第三种,将awk_script放入脚本文件并以 #!/bin/awk -f 作为首行,给予该脚本可执行权限,然后在shell下通过键入该脚本的脚本名调用之。

三、awk脚本

awk脚本可以由一条或多条awk_cmd组成,对于多个awk_cmd,一个awk_cmd完成后,应该另起一行,以便进行隔。 

awk_cmd由两部分组成: awk_pattern { actions }。

另外,在awk命令中直接使用awk_script时,awk_script也可以被分成多行书写,但必须确保整个awk_script被单引号括起来。

awk命令的一般形式:

awk ' BEGIN { actions }

awk_pattern1 { actions }

............

awk_patternN { actions }

END { actions }

' inputfile

其中 BEGIN { actions } 和 END { actions } 是可选的。

在awk脚本中可以使用AWK本身内置变量,如下: 

ARGC 命令行变元个数

ARGV 命令行变元数组

FILENAME 当前输入文件名

FNR 当前文件中的记录号

FS 输入域分隔符,默认为一个空格

RS 输入记录分隔符

NF 当前记录里域个数

NR 到目前为止记录数

OFS 输出域分隔符

ORS 输出记录分隔符

awk脚本的运行过程:

① 如果BEGIN 区块存在,awk执行它指定的actions。

② awk从输入文件中读取一行,称为一条输入记录。(如果输入文件省略,将从标准输入读取)

③ awk将读入的记录分割成字段,将第1个字段放入变量$1中,第2个字段放入$2,以此类推。$0表示整条记录。字段分隔符使用shell环境变量IFS或由参数指定。

④ 把当前输入记录依次与每一个awk_cmd中awk_pattern比较,看是否匹配,如果相匹配,就执行对应的actions。如果不匹配,就跳过对应的actions,直到比较完所有的awk_cmd。

⑤ 当一条输入记录比较了所有的awk_cmd后,awk读取输入的下一行,继续重复步骤③和④,这个过程一直持续,直到awk读取到文件尾。

⑥ 当awk读完所有的输入行后,如果存在END,就执行相应的actions。

1)input_file可以是多于一个文件的文件列表,awk将按顺序处理列表中的每个文件。

2)一条awk_cmd的awk_pattern可以省略,省略时不对输入记录进行匹配比较就执行相应的actions。一条awk_cmd的actions 也可以省略,省略时默认的动作为打印当前输入记录,即{print $0} 。一条awk_cmd中的awk_pattern和actions不能同时省略。

3) BEGIN区块和END区块别位于awk_script的开头和结尾。awk_script中只有END区块或者只有BEGIN区块是被允许的。如果awk_script中只有BEGIN { actions } ,awk不会读取input_file。

4) awk把输入文件的数据读入内存,然后操作内存中的输入数据副本,awk不会修改输入文件的内容。

5) awk的总是输出到标准输出,如果想让awk输出到文件,可以使用重定向。

3.1.awk_pattern

awk_pattern模式部分决定actions动作部分何时触发及触发actions。

awk_pattern可以是以下几种类型:

1) 正则表达式用作awk_pattern: /regexp/

注意,正则表达式regexp必须被/包起来

awk中正则表达式匹配操作中经常用到的字符:

\ ^ $ . [] | () * // :通用的regexp元字符

+ : 匹配其前的单个字符一次以上,是awk自有的元字符,不适用于grep或sed等

? : 匹配其前的单个字符1次或0次,是awk自有的元字符,不适用于grep或sed等

关于正则表达式的更多内容请参《正则表达式》

举例:

awk '/ *\$0\.[0-9][0-9].*/' input_file

比如,行内容为$0.99. helllo的行就可以和上面的正则表达式相配

2) 布尔表达式用作awk_pattern,表达式成立时,触发相应的actions执行。

① 表达式中可以使用变量(如字段变量$1,$2等)和/regexp/

② 布尔表达式中的操作符:

关系操作符: = == !=

匹配操作符: value ~ /regexp/ 如果value匹配/regexp/,则返回真

value !~ /regexp/ 如果value不匹配/regexp/,则返回真

举例: awk '$2 > 10 {print "ok"}' input_file

awk '$3 ~ /^d/ {print "ok"}' input_file

③ &&(与) 和 ||(或) 可以连接两个/regexp/或者布尔表达式,构成混合表达式。!(非) 可以用于布尔表达式或者/regexp/之前。

举例: awk '($1 10) {print $0 "ok"}' input_file

awk '/^d/ || /x$/ {print $0 "ok"}' input_file

④ 其它表达式用作awk_script,如赋值表达式等

举例:

 awk '(tot+=$6); END{print "total points :" tot }' input_file // 分号不能省略

awk 'tot+=$6 {print $0} END{print "total points :" tot }' input_file // 与上面等效

当使用赋值表达式时,表示如果赋值后的变量是数字的话,如果为非0,就匹配,否则不匹配;如果为字符串的话,非空就为匹配,否则不匹配。

awk内置字符串函数:

gsub(r,s)           在整个$0中用s替代r

awk 'gsub(/name/,"xingming") {print $0}' temp

gsub(r,s,t)         在整个t中用s替代r

index(s,t)          返回s中字符串t的第一位置

awk 'BEGIN {print index("Sunny","ny")}' temp     返回4

length(s)           返回s的长度

match(s,r)          测试s是否包含匹配r的字符串

awk '$1=="J.Lulu" {print match($1,"u")}' temp    返回4

split(s,a,fs)       在fs上将s分成序列a

awk 'BEGIN {print split("12#345#6789",myarray,"#")"'

返回3,同时myarray[1]="12", myarray[2]="345", myarray[3]="6789"

sprint(fmt,exp)     返回经fmt格式化后的exp

sub(r,s)   从$0中最左边最长的子串中用s代替r(只更换第一遇到的匹配字符串)

substr(s,p)         返回字符串s中从p开始的后缀部分

substr(s,p,n)       返回字符串s中从p开始长度为n的后缀部分

awk字符串连接操作 

[chengmo@centos5 ~]$ awk 'BEGIN{a="a";b="b";c=(a""b);print c}'      

ab 

2.7.     printf函数的使用:

字符转换: echo "65" |awk '{printf "%c\n",$0}'    输出A

 awk 'BEGIN {printf "%f\n",999}'        输出999.000000

格式化输出:awk '{printf "%-15s %s\n",$1,$3}' temp 将第一个域全部左对齐显示

2.8.     其他awk用法:

    向一行awk命令传值:

awk '{if ($5

who | awk '{if ($1==user) print $1 " are in " $2 ' user=$LOGNAME 使用环境变量

awk脚本命令:

开头使用 !/bin/awk -f  ,如果没有这句话自含脚本将不能执行,例子:

!/bin/awk -f

# all comment lines must start with a hash '#'

# name: student_tot.awk

# to call: student_tot.awk grade.txt

# prints total and average of club student points

# print a header first

BEGIN

{

print "Student    Date   Member No.  Grade  Age  Points  Max"

print "Name  Joined Gained  Point Available"

print"========================================================="

}

# let's add the scores of points gained

(tot+=$6);

# finished processing now let's print the total and average point

END

{

    print "Club student total points :" tot

    print "Average Club Student points :" tot/N

}

2.9.     awk数组:

awk的循环基本结构

For (element in array) print array[element]

awk 'BEGIN {record="123#456#789";split(record,myarray,"#")} 

END { for (i in myarray) {print myarray[i]} }

3.0  awk中自定义语句

一.条件判断语句(if)

if(表达式) #if ( Variable in Array )

语句1

else

语句2

格式中"语句1"可以是多个语句,如果你为了方便Unix awk判断也方便你自已阅读,你最好将多个语句用{}括起来。Unix awk分枝结构允许嵌套,其格式为:

if(表达式)

{语句1}

JTBC网站内容管理系统5.0.3.1
JTBC网站内容管理系统5.0.3.1

JTBC CMS(5.0) 是一款基于PHP和MySQL的内容管理系统原生全栈开发框架,开源协议为AGPLv3,没有任何附加条款。系统可以通过命令行一键安装,源码方面不基于任何第三方框架,不使用任何脚手架,仅依赖一些常见的第三方类库如图表组件等,您只需要了解最基本的前端知识就能很敏捷的进行二次开发,同时我们对于常见的前端功能做了Web Component方式的封装,即便是您仅了解HTML/CSS也

下载

else if(表达式)

{语句2}

else

{语句3}

[chengmo@localhost nginx]# awk 'BEGIN{ 

test=100;

if(test>90)

{

    print "very good";

}

else if(test>60)

{

    print "good";

}

else

{

    print "no pass";

}

}'

very good

 

每条命令语句后面可以用“;”号结尾。

 

二.循环语句(while,for,do)

1.while语句

格式:

while(表达式)

{语句}

例子:

[chengmo@localhost nginx]# awk 'BEGIN{ 

test=100;

total=0;

while(i

{

    total+=i;

    i++;

}

print total;

}'

5050

2.for 循环

for循环有两种格式:

格式1:

for(变量 in 数组)

{语句}

例子:

[chengmo@localhost nginx]# awk 'BEGIN{ 

for(k in ENVIRON)

{

    print k"="ENVIRON[k];

}

}'

AWKPATH=.:/usr/share/awk

OLDPWD=/home/web97

SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass

SELINUX_LEVEL_REQUESTED=

SELINUX_ROLE_REQUESTED=

LANG=zh_CN.GB2312

。。。。。。

说明:ENVIRON 是awk常量,是子典型数组。

格式2:

for(变量;条件;表达式)

{语句}

例子:

[chengmo@localhost nginx]# awk 'BEGIN{ 

total=0;

for(i=0;i

{

    total+=i;

}

print total;

}'

5050

3.do循环

格式:

do

{语句}while(条件)

例子:

[chengmo@localhost nginx]# awk 'BEGIN{ 

total=0;

i=0;

do

{

    total+=i;

    i++;

}while(i

print total;

}'

5050

 

以上为awk流程控制语句,从语法上面大家可以看到,与c语言是一样的。有了这些语句,其实很多shell程序都可以交给awk,而且性能是非常快的。

break 当 break 语句用于 while 或 for 语句时,导致退出程序循环。 

continue 当 continue 语句用于 while 或 for 语句时,使程序循环移动到下一个迭代。 

next 能能够导致读入下一个输入行,并返回到脚本的顶部。这可以避免对当前输入行执行其他的操作过程。 

exit 语句使主输入循环退出并将控制转移到END,如果END存在的话。如果没有定义END规则,或在END中应用exit语句,则终止脚本的执行。 

NR与FNR:

QUOTE:

A.awk对多输入文件的执行顺序是,先将代码作用于第一个文件(一行行读入),然后该重复的代码又作用于第二个文件,再作用于第三个文件。

B.awk对多输入文件的执行顺序产生了行序号的问题。当第一个文件执行完,下次读入第二个文件,那么第二个文件的第一行怎么算呢?如果又计为1的话,那不就两个1了么?(因为第一个文件也有第一行)。这就是NR和FNR的问题。

   NR :全局行数(第二个文件的第一行接着第一个文件尾行数顺序计数)

   FNR:当前文件自身的行数(不考虑前几个输入文件的自身行数及总数)

         例如:data1.txt中有40行,data2.txt中有50行,那么awk ‘{}’ data1.txt data2.txt

                  NR  的值依次为:1,2……40,41,42……90

                   FNR的值依次为:1,2……40, 1, 2……50 

getline函数说明:

awk 的 getline语句用于简单地读取一条记录。如果用户有一个数据记录类似两个物理记录,那么getline将尤其有用。它完成一般字段的分离(设置字段变量$0 FNR NF NR)。如果成功则返回1,失败则返回0(到达文件尾)。

QUOTE:

A.getline从整体上来说,应这么理解它的用法:

            当其左右无重定向符 | 或

            var 或$0(无变量);应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到

            的返回结果是隔行的。

            当其左右有重定向符 | 或

            awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。

B.getline用法大致可分为三大类(每大类又分两小类),即总共有6种用法。代码如下:

QUOTE:

nawk ‘BEGIN{“cat data.txt”|getline d; print d}’ data2.txt 

nawk ‘BEGIN{“cat data.txt”|getline; print $0}’ data2.txt

nawk ‘BEGIN{getline d

nawk ‘BEGIN{getline

      以上四行代码均实现“只打印data.txt文件的第一行”(若打印全部行,用循环)

eg. nawk ‘BEGIN{FS=”:”;while(getline0){print $1}}’ data.txt

QUOTE:

nawk ‘{getline d; print d”#”$3}’ data.txt

 awk首先读入第一行,接着处理getline函数,然后把下一行指定给变量d,再先打印d,由于d后面有换行符,所以后面紧跟的#会覆盖d,后面的$3同样也会覆盖d。

QUOTE:

nawk ‘{getline; print $0”#”$3}’ data.txt

awk首先读入第一行接着处理getline函数,然后把下一行指定给$0,现在的$0已经是下一行内容,后面的#和$3(从$0中取)会覆盖$0的内容。

在awk中,有时需要调用系统工具来完成awk不擅长的工作,awk提供的system命令可以用来执行,但收不到外部工具的输出结果。好在可以运用getline来满足这个需求。例如

test.awk:

{

   datecommand="/bin/date -j -f \"%d/%b/%Y:%H:%M:%S\" " $olddatestr " \"+%Y%m%d %H%M%S\"";

   datecommand | getline newdatestr 

   close(datecommand);

}

 

外部命令需要awk占用一个文件描述符,而awk最多能打开的文件有一个上限,而且不大(比如说16),所以最后做一个close是好习惯。把命令串定义为一个变量也是为了close的时候方便

更多awk命令详解 相关文章请关注PHP中文网!

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

15

2026.01.29

clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址
clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址

clawdbot龙虾机器人官网入口:https://clawd.bot/,clawdbot ai是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

12

2026.01.29

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

8

2026.01.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

557

2026.01.28

包子漫画在线官方入口大全
包子漫画在线官方入口大全

本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

197

2026.01.28

ao3中文版官网地址大全
ao3中文版官网地址大全

AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

333

2026.01.28

php怎么写接口教程
php怎么写接口教程

本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

11

2026.01.28

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

16

2026.01.28

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

11

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

PHP入门到实战消息队列RabbitMQ
PHP入门到实战消息队列RabbitMQ

共22课时 | 1.3万人学习

成为PHP架构师-自制PHP框架
成为PHP架构师-自制PHP框架

共28课时 | 2.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号