awk manual.
发布日期:2021-11-16 18:19:09
浏览次数:4
分类:技术文章
本文共 8500 字,大约阅读时间需要 28 分钟。
http://www.lupaworld.com/94908/viewspace-44960.html
1.调用awk:
第一种方式:命令行方式 awk [-F field-separator] 'commands' input-file(s) [-F域分隔符]是可选的,因为awk使用空格作为缺省的域分隔符,因此如果要浏览域间有空格的文本,不必指定这个选项,如果要浏览诸如passwd文件,此文件各域以冒号作为分隔符,则必须指明-F选项,如: awk -F: 'commands' input-file 第二种方式是将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它。 第三种方式是将所有的awk命令插入一个单独文件,然后调用: awk -f awk-scrīpt-file input-files(s) -f选项指明在文件awk_scrīpt_file中的awk脚本,input_file(s)是使用awk进行浏览的文件名。 2.awk脚本 2.1 模式和动作 任何awk语句都由模式和动作组成。在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。 模 式可以是任何条件语句或复合语句或正则表达式。模式包括两个特殊字段 BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文本开始执行。END语 句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志。 2.2 域和记录 使用$1,$3表示参照第1和第3域,注意这里用逗号做域分隔。如果希望打印一个有5个域的记录的所有域,可使用$0,意即所有域。 为打印一个域或所有域,使用print命令。这是一个awk动作 (1) 抽取域 (2) 保存awk输出 $ awk '{print $0}' grade.txt > wow 使用这种方法,显示屏上不会显示输出结果。直接输出到文件。 使用tee命令,在输出文件的同时,输出到屏幕 $ awk '{print $0}' grade.txt | tee delete_me_and_die (3) 使和标准输入 使用awk脚本输入文件格式: ● $ belts.awk grade_student.txt ● $ belts.awk < grade2.txt ● $ grade2.txt | belts.awk (4) 打印所有记录 $ awk '{print $0}' grade.txt (5) 打印单独记录 $ awk '{print $1,$4}' grade.txt (6) 打印报告头 域间使用/t进行划分。下划线使用/n强迫启动新行 $ awk 'BEGIN {print "Name Belt/n----------------------------------"} {print $1"/t"$4}' grade.txt (7) 打印信息尾 使用END语句 $ awk 'BEGIN {print "Name/n---------"} {print $1} END {"end-of-report"}' grade.txt
2.5 条件操作符 (1) 匹配: $ awk '{if ($4~/Brown/) print $0}' grade.txt 如果在文本中查询字符串"Brown",使用/Brown/ $ awk '$0 ~ /Brown/' grade.txt (2) 精确匹配 $ awk '$3 == "48" {print $0}' grade.txt $ awk '{if ($3=="48") print $0}' grade.txt (3) 不匹配 $ awk '$0 !~ /Brown/' grade.txt $ awk '{if($4 !~ /Brown/) print $0' grade.txt 精确不匹配 $ awk '$4 != "Brwon-2" {print $0}' grade.txt (4) 小于 $ awk '{if ($6 < $7) print $0 "$1 Try better at the next comp"}' grade.txt (5) 小于等于 $ awk '{if ($6 <= $7) print $1}' grade.txt (6) 大于 $ awk '{if ($6 > $7) print $1}' grade.txt (7) 设置大小写 $ awk '/[Gg]reen/' grade.txt (8) 任意字符 抽取名字,其记录第一域的第四个字符是a,使用句点.。表达式/^...a/意为行首前三个字符任意,第四个是a,尖角符号代表行首。 $ awk '$1 ~/^...a/' grade.txt (9) 或关系匹配 为抽取级别为yellow或brown的记录,使用竖线符|。意为匹配|两边模式之一。注意,使用竖线符时,语句必须用圆括号括起来。 $ awk '$0~/(Yellow|Brown)/' grade.txt (10) 行首 $ awk '/^48/' input-file (11) AND && 意味着两边匹配均为真 $ awk '{if ($1 == "P.Bunny" && $4 == "Yellow") print $0}' grade.txt (12) OR $ awk '{if ($4 == "Yellow" || $4 ~ /Brown/) print $0}' grade.txt
2.6 awk内置变量 最常用的一些变量 -------------------------------------------------------- ARGC 命令行参数个数 ARGV 命令行参数排列 ENVIRON 支持队列中系统环境变量的使用 FILENAME awk浏览的文件名 FNR 浏览文件的记录数 FS 设置输入域分隔符,等价于命令行-F选项 NF 浏览记录的域个数 NR 已读的记录数 OFS 输出域分隔符 ORS 输出记录分隔符 RS 控制记录分隔符 --------------------------------------------------------
2.7 NF、NR和FILENAME NR代表记录处数 $ awk 'END {print NR}' grade.txt $ 5 打印所有学生的记录,并带有其记录号,并在END部分打印输入文件名 NF显示一条记录中有几个域 $ awk '{print NF,NR,$0}END{print FILENAME}' grade.txt 在从文件中抽取信息时,先检查文件中是否有记录。使用AND实现 $ awk '{if (NR > 0 && $4~/Brown/) print $0}' grade.txt NF的强大功能是将变量$PWD的返回值传入awk并显示其目录。这里需要指定域分隔符 $ pwd /usr/local/etc $ echo $PWD | awk -F/ '{print $NF}' 另一个例子是显示文件名: $ echo "/usr/local/etc/rc.sybase" | awk -F/ '{print $NF}' rc.sybase
2.8 awk操作符 awk使用操作符,基本表达式可以划分为数字型、字符串型、变量型、域及数组元素, ----------------------------------------------------- = += *= /= %= ^= 赋值操作符 ? 条件表达操作符 || && ! 并、与、非 ~ !~ 匹配操作符,包括匹配与不匹配 < <= == != >> 关系操作符 + - * / % ^ 算术操作符 ++ -- 前缀和后缀 ----------------------------------------------------- (1)设置输入域到域变量名 一般的变量名设置方式为name = $n,这里name为调用的域变量名,n为实际域号。 例如,设置学生域名为name,级别域名为belt,操作为name = $1; belts = $4。注意分号,它分隔awk命令。 $ awk '{name = $1; belts = $4; if(belts ~/Yellow/) print name " is belt " belts}' grade.txt $ P.Bunny is belt Yellow
(2) 域值比较操作 有两种方式测试一数值域是否小于另一数值域 1)在BEGIN中给变量名赋值。 2)在关系操作中使用实际数值。 查询所有比赛中得分在27点的学生 $ awk '{if ($6 < 27) print $0}' grade.txt J.Lulu 06/99 48317 green 9 24 26 J.Troll 07/99 4842 Brown-3 12 26 26 使用BEGIN $ awk 'BEGIN {BASELINE="27"} {if ($6 < BASELINE) print $0}' grade.txt
(3) 修改数值域取值 当在awk中修改任何域时,修改的只是缓存里的awk复本。awk会在变量NR和NF变量中反映出修改痕迹。 $1=$1+5,会将域1数值加5,但要确保赋值域其子集为数值型。 修改M.Tansley的目前级别分域, awk '{if ($1 == "M.Tansley") $6=$6-1; print $1, $6, $7}' grade.txt
(4) 修改文本域 修改文本域即对其重新赋值。需要做的就是赋给一个新的字符串。 $ awk '{if ($1 == "J.Troll") ($1 = "J.L.Troll"); print $1}' grade.txt
(5) 只显示修改记录 在模式后面使用花括号将只打印修改部分。取得模式,再根据模式结果实施操作。 $ awk '{if ($1 == "J.Troll") {$1 = "J.L.Troll"; print $1}}' grade.txt
(6) 创建新的输出域 如创建一个基于其他域的加法新域{$4 = $2 + $3},假定记录包含3上域,则域4为新建域。 在文件grade.txt中创建新域8保存域目前级别分与域域最高级别分的减法值。表达式为'{$8 = $7 - $6}',语法首先测试域目前级别分小于域最高组别分。 $ awk 'BEGIN {print "Name/t Difference"} {if ($6 < $7) {$8 = $7 - $6; print$1, $8}}' grade.txt 可以创建新域,赋给更有意义的变量名 $ awk 'BEGIN {print "Name/t Difference"} {if ($6 < $7) {diff = $7 - $6; print$1, diff}}' grade.txt
(7) 增加列值 为增加列数或进行运行结果统计,使用符号 +=。增加的结果赋给符号左边变量值,增加到变量的域在符号右边。例如将$1加入变量total,表达式为total+=$1。 将所有学生的'目前级别分'加在一起,方法是tot+=$6,tot即为awk浏览的整个文件的域6结果总和。 $ awk '{(tot+=$6)}; END {print "Club student total points : " tot}' grade.txt Club student total points : 155
(8) 文件长度相加 在目录中查看文件时,快速查看所有文件的长度及其总和,但要排除子目录。使用ls -l,然后管道输出到awk $ ls -l | awk '/^[^d]/ {print $9"/t"$5} {tot+=$5} END {print "total KB : " tot}' data.f 193 grade.txt 179 grepstring 7 local.cshrc 136 local.login 157 local.profile 174 results.txt 2129 wow 179 total KB : 4690
(9) 内置的字符串函数 awk内置字符串函数 ----------------------------------------------------------- gsub(r,s) 在整个$0中用s替代r gsub(r,s,t) 在整个t中用s替代r index(s,t) 返回s中字符串t的第一个位置 length(s) 返回s长度 match(s,r) 测试s是否包含匹配r的字符串 split(s,a,fs) 在fs上将s分成序列a sprint(fmt,exp) 返回经fmt格式化后的exp sub(r,s) 用$0中最左边最长的子串代替s substr(s,p) 返回字符串s中从p开始的后缀部分 substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分 ----------------------------------------------------------- ■gsub:
■index: $ awk 'BEGIN {print index("Bunny", "ny")}' grade.txt 4
■length: $ awk '$1 == "J.Troll" {print length($1)" "$1}' grade.txt 7 J.Troll $ awk 'BEGIN{print length("A FEW GOOD MEN")}' 14
■match:如果不存在,返回0
■split 返回字符串数组元素个数。 $ awk 'BEGIN {print split("123#456#678", myarray, "#")}' 3
■sub 使用sub发现并替换模式的第一次出现位置。字符串STR包含'poped popo pill',执行下列sub命令 sub(/op/, "op", STR)。结果 'pOPed pope pill' $ awk '$1 == "L.Tansley" {print substr($1, 1, 5)}' grade.txt L.Tan
■substr: 它按照起始位置及长度返回字符串的一部分。 $ awk '$1 == "L.Tansley" {print substr($1, 1, 5)}' grade.txt L.Tan substr的另一种形式是返回字符串后缀或指定位置后面的字符 $ awk '{print substr($1, 3)}' grade.txt 在BEGIN部分定义字符串,在END部分返回从第t个字符开始抽取的子串。 $ awk 'BEGIN {STR="A FEW GOOD MEN"} END {print substr(STR, 7)}' grade.txt GOOD MEN
■从shell中向awk传入字符串: 通过管道把字符串传入awk $ echo "Stand-by" | awk '{print length($0)}' 8 设置文件名为一变量,管道输出到awk,返回不带扩展名的文件名 $ STR="mydoc.txt" $ echo $STR | awk '{print substr($STR,1,5)}' mydoc
(10)字符串屏蔽序列 使用字符串或正则表达式时,有时需要在输出中加入一新行或查询一元字符。 awk中使用的屏蔽序列 ------------------------------------------------------------ /b 退格键 /t tab键 /f 走纸换页 /ddd 八进制值 /n 新行 /c 任意其他特殊字符,例如//为返斜线符号 /r 回车键 ------------------------------------------------------------ 打印May Day,中间夹tab键,后跟两个新行,再打印May Day,这次使用八进制数 $ awk 'BEGIN{print "May/tDay/n/nMay/t/104/141/171"}'
(11) awk输出函数printf awk printf修饰符 ---------------------------------------------------------------- - 左对齐 Width 域的步长,用0表示0步长 .prec 最大字符串长度,或小数点右边的位数 ----------------------------------------------------------------
awk printf格式 ------------------------------------------------------------- %c ASCII字符 %d 整数 %e 浮点数,科学记数法 %f 浮点数,例如(123.44) %g awk决定使用哪种浮点数转换e或者f %o 八进制数 %s 字符串 %x 十六进制数 -------------------------------------------------------------- ■ 字符转换 观察ASCII码中65的等价值。管道输出65到awk。 $ echo "65" | awk '{printf "%c/n", $0}' A 当然也可以按同样方式使用awk得到同样结果 $ awk 'BEGIN {printf "%c/n", 65}' A 所有的字符转换都一样,下面的例子表示进行浮点数转换后'999'的输出结果。整数传入后被加了小数点。 $ awk 'BEGIN {printf "%f/n", 999}'
■ 格式化输出 打印所有的学生名字和序列号,要求名字左对齐,15个字符长度,后跟序列号。注意/n换行符放在最后一个指示符后面。输出将自动分成两列。 $ awk '{printf "%-15s %s/n", $1, $3}' grade.txt M.Tansley 48311 J.Lulu 48317 P.Bunny 48 J.Troll 4842 L.Tansley 4712 加入文本注释帮助理解报文含义。可在正文前嵌入头信息。 $ awk 'BEGIN {print "Name /t/tS.Number"} {printf "%-15s %s/n", $1, $3}' grade.txt Name S.Number M.Tansley 48311 J.Lulu 48317 P.Bunny 48 J.Troll 4842 L.Tansley 4712
■ 向一行awk命令传值 在查看awk脚本前,先来查看怎样在awk命令行中传递变量。 awk执行前将值传入awk变量,需要将变量放在命令行中,格式如下: awk 命令变量 = 输入文件值 在命令行中设置变量AGE等于10,然后传入awk中,查询年龄在10岁以下的所有学生 $ awk '{if ($5 < AGE) print $0}' AGE=10 grade.txt 要快速查看文件系统空间容量,观察其是否达到一定水平。 $ df -k | awk '($4 ~/^[0-9]/) {if ($4 < TRIGGER) print $6"/t"$4}' TRIGGER=56000 使用who命令,who命令第一列包含注册用户名。 # who | awk '{print $1 " is logged on"}' root is logged on root is logged on sun is logged on awk传入环境变量。使用环境变量LOGNAME支持当前用户名。 # who | awk '{if ($1 == user) print $1 " you are connected to" $2}' user=$LOGNAME root you are connected toconsole root you are connected topts/4
转载地址:https://blog.csdn.net/taoshengyang/article/details/6291849 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
很好
[***.229.124.182]2024年04月07日 05时41分47秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
PHP使用curl_multi_add_handle并行处理
2019-04-27
NP问题
2019-04-27
AT&T与Intel汇编语言的比较
2019-04-27
javascript解析json
2019-04-27
WinDbg安装与使用
2019-04-27
推荐阅读的多核编程技术书籍
2019-04-27
维基百科上的算法和数据结构链接很强大
2019-04-27
选择排序
2019-04-27
PHP session回收机制
2019-04-27
最新的全球编程语言,操作系统,web服务器等使用率分析报告
2019-04-27
用C语言写PHP扩展
2019-04-27
PHP Extension programming
2019-04-27
海量数据处理
2019-04-27
PHP防止注入攻击
2019-04-27
多路IO复用模型 select epoll 等
2019-04-27
Linux Epoll介绍和程序实例
2019-04-27
output_buffering详细介绍
2019-04-27
php缓冲 output_buffering和ob_start
2019-04-27
php error_reporting 详解
2019-04-27
剖析PHP中的输出缓冲
2019-04-27