一天一个shell命令 linux文本内容操作系列-awk命令详解

简介

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

使用方法

awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

调用awk

有三种方式调用awk

说明:

awk被设计用于数据流,能够对列和行进行操作。而sed更多的是匹配,进行替换和删除。
awk有很多内建的功能,比如数组,函数等。灵活性是awk的最大优势。

awk的结构
awk '
BEGIN{ print "start"}
pattern { commands }
END{ print "end"}'
file
为了偏于观看,我打了回车,实际上是一行

一个awk脚本通常是3部分
1. BEGIN语句块
2. 能够使用模式匹配的通用语句块
3. END语句块
 他们任何一部分都可以不出现在脚本中。脚本通常包含在双引号或者单引号内。
 例如:

awk 'BEGIN{i=0}{i++}END{print i}' filename

工作原理

awk命令的工作方式如下:

1. 执行BEGIN{commands}语句块中的语句
2. 从文件或者stdin中读取一行,然后执行pattern{commands}. 迭代直到全部读取完毕
3. 最后执行END{commands}语句块

再次提醒,他们任何一部都可以没有

而awk的功能也远不止如此

入门实例:

代码如下:

echo | awk '{var1="v1";var2="v2";var3="v3"; print var1,var2,var3;}' 
打印: v1 v2 v3

解释:逗号为定界符(分隔符)

echo | awk '{var1="v1";var2="v2";var3="v3"; print var1"-"var2"-"var3;}'

打印v1-v2-v3

解释:双引号为连接符

其他任何符号,都不能正常输出v1,v2,v3

解读--help(一个非常庞大复杂的帮助文档,官方用了410页的篇幅PDF来介绍,如果我只言片语,你信我自己都不信。。)

用法: awk [POSIX 或 GNU 风格选项] -f 脚本文件 [--] 文件 ...
用法: awk [POSIX 或 GNU 风格选项] [--] '程序' 文件 ...
POSIX 选项:             GNU 长选项:
     -f 脚本文件        --file=脚本文件
    -F fs            --field-separator=fs
指定输入文本分隔符,fs是一个字符串或者是一个正则表达式,
    -v var=val        --assign=var=val
将外部变量值付给var
     -m[fr] val
     -O            --optimize
启用一些优化程序的内部表示。
     -W compat        --compat
在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
     -W copyleft        --copyleft
打印简短的版权信息
    -W copyright        --copyright
打印短版的通用公共许可证,然后退出
     -W dump-variables[=file]    --dump-variables[=file]
打印全局变量,其类型,提交的最终值的排序列表。
    -W exec=file        --exec=file
与-f类似,但与他有两点不同,(我回头把相关文档上传,太长)
    -W gen-po        --gen-po
(内容太多)
    -W help            --help 打印帮助
    -W lint[=fatal]        --lint[=fatal]
警告可疑或不移植到其他的awk实现的结构
     -W lint-old        --lint-old
打印关于不能向传统unix平台移植的结构的警告
     -W non-decimal-data    --non-decimal-data
启用自动输入数据的解释,八进制和十六进制值
     -W profile[=file]    --profile[=file]
启用awk程序剖析
     -W posix        --posix
在严格意义上的POSIX模式运作。
     -W re-interval        --re-interval
允许间隔表达式在正则表达式上
    -W source=program-text    --source=program-text
     -W traditional        --traditional
传统的Unix awk的正则表达式匹配
     -W usage        --usage
     -W use-lc-numeric    --use-lc-numeric
解析数字输入时,强制使用的语言环境中的小数点字符
 数据
 -W version        --version
提交错误报告请参考“gawk.info”中的“Bugs”页,它位于打印版本中的“Reporting
 Problems and Bugs”一节

注意:gawk是awk的GNU版本,即使help ,在ubuntu下也需要先安装gawk

这回我们就不解读了,为了增加大家的信息和乐趣,先来点基本的:

部分特殊变量:

NR: 表示记录数量,在执行过程中对应于行号
NF:表示字段数量,在执行过程中对应于当前行的字段数
$0: 这个变量包含执行过程中当前行的文本内容
$1: 第一个字段的文本内容
$2: 第二个字段的文本内容

例子:

例1.

代码如下:

echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7"|\#这个\是在窗口中写多行命令用的 
awk '{ 
print "Line no:"NR",No of fields:"NF, "$0="$0,"$1="$1,"$2="$2,"$3="$3 
}'

小注一下:$1是打印第一个,$NF打印最后一个字段,$(NF-1)打印倒数第二个

 例2.

seq 5 | awk 'BEGIN{ sum=0;print "Summation:"}{print $1"+";sum+=1}END{print "==";print sum}'

这个例子用到了基本格式。

BEGIN中 初始化了sum,打印Summation
中间模块打印了第一列,然后给sum+1

END中打印了sum

 例3. 关于-v 外部变量

代码如下:

$ VAR=10000
$echo | awk –v VARIABLE=$VAR'{print VARABLE}'

还有另一种灵活的方法可以将多个外部变量传递给awk,例如:

代码如下:

$var1="value1" var2="value2"
$echo | awk '{print v1,v2}' v1=$var1 v2=$var2

如果来自文件

awk '{print v1,v2}' v1=$var1 v2=$var2 filename

例4

$awk 'NR < 5' #行号小于5
$awk 'NR==1,NR==4' #行号在1到5之间的行
$awk '/linux/' #包含样式linux的行(可以用正则表达式指定样式)
$awk '!/linux/' #不包含样式linux的行

这次先写这些,争取在花2个篇幅能把awk做个比较全面的认识。

awk补充

之前我们学习了awk基本入门,我惊喜的发现有awk一篇详细文章,有写念头,不能全部转载,转化成自己的方式来写一些。

主讲内置变量和部分字符串函数

内置变量(有翻译特殊变量和环境变量,按照官方翻译为内置变量)


变量


说明

$n 当前记录的第n个字段,字段间由FS分隔。
$0 完整的输入记录。
ARGC 命令行参数的数目。
ARGIND 命令行中当前文件的位置(从0开始算)。
ARGV 包含命令行参数的数组。
BINMODE 在非POSIX系统上,这个变量指定的所有I / O使用二进制模式
CONVFMT 数字转换格式(默认值为%.6g)
ENVIRON 环境变量关联数组。
ERRNO 最后一个系统错误的描述。
FIELDWIDTHS 字段宽度列表(用空格键分隔)。
FILENAME 当前文件名。
FNR 同NR,但相对于当前文件
FPAT
这是一个正则表达式(字符串),告诉gawk基于匹配正则表达式的文本来创建字段

FS 字段分隔符(默认是任何空格)。
IGNORECASE 如果为真,则进行忽略大小写的匹配。
LINT
当这个变量为真(非零或非空),gawk的行为犹如"--lint"命令行选项

NF 当前记录中的字段数。
NR 当前记录数。
OFMT 数字的输出格式(默认值是%.6g)。
OFS 输出字段分隔符(默认值是一个空格)。
ORS 输出记录分隔符(默认值是一个换行符)。
PROCINFO
这个数组的元素提供访问运行awk程序的信息

RLENGTH 由match函数所匹配的字符串的长度。
RS 记录分隔符(默认是一个换行符)。
RT 每次一条记录被读取的设置
RSTART 由match函数所匹配的字符串的第一个位置。

SUBSEP


数组下标分隔符(默认值是\034)。

TEXTDOMAIN 此变量用于程序的国际化

蓝色为新增加的内置变量。

简单举例:

1.
01.sed 1q /etc/passwd | awk '{ FS = ":"; print $1 }'

打印密码第一行,用冒号分隔符

2.

代码如下:

awk 'END{print FILENAME}' awk.txt

打印文本FILENAME

3. seq 100 | awk 'NR==4,NR==6'

打印4到6行

再介绍几个awk内置的字符串函数,也讲一部分。

length(string):
 返回字符串的长度

index(string,serch_string):
返回search_string在字符串中出现的位置

split(string,array,delimiter):
用定界符生成一个字符串列表,并将该列表存入数组

substr(string,array,delimiter):
 在字符串中用字符起止便宜量生成子串,并返回该子串

sub(regex,replacement_str,string):
将正则表达式匹配到的第一处内容替换成replacement_str

gsub(regex,replacement_str,string):
和sub()类似。不过该函数会替换正则表达式匹配到的所有内容

match(regex,string):
检查正则表达式是否能够匹配字符串。如果能够匹配,返回非0值;否则,返回0.match()有两个相关的特殊变量,分别是RSTART喝RLENGTH。变量RSTART包含正则表达式所匹配内容的其实位置,而变量RLENGTH包含正则表达式所匹配内容的长度。

举例:

1.$ awk '{ sub(/test/, "mytest"); print }' testfile

在整个记录中匹配,替换只发生在第一次匹配发生的时候

2.$ awk '{ sub(/test/, "mytest"); $1}; print }' testfile

在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候

3.$ awk '{ print index("test", "mytest") }' testfile

实例返回test在mytest的位置,结果应该是3

4.$ awk '{ print length( "test" ) }'

实例返回test字符串的长度。

awk补充二

这节可能要写的比较粗了,时间太少。

一. 内置函数
注意一种约定俗称语法习惯: [a]代表a可选.

数字函数(Numeric Functions)


函数名


说明

atan2(y,x) 返回y/x弧的反正切
cos(x) 返回x的余弦
exp(x) 返回x的指数
int(x) 返回最靠近的整数,风向标指向0
log(x) 返回x的自然对数
rand() 返回随机数
sin(x) 返回x的正弦
sqrt(x) 返回x的正平方根
srand([x]) 生成随机数,可以设置起点

字符串操作函数(String-Manipulation Functions)
注意:蓝色部分为gawk特有,awk没有此函数功能。


函数名


说明

asort(source [, dest [, how ] ]) 返回数组元素数(内容较多)
asorti(source [, dest [, how ] ]) 同asort,(有细微差别)
gensub(regexp, replacement, how [, target]) 搜索正则表达式RegExp匹配的regexp
gsub(regexp, replacement [, target]) 将正则表达式匹配的第一处内容替换成replacement_str
index(in, find) 返回find在字符串in中出现的位置
length([string]) string 中的字符数
match(string, regexp [, array]) 检查正则表达式能否匹配字符串
patsplit(string, array [, fieldpat [, seps ] ])
划分件到由fieldpat定义的字符串,并存储在array里,分隔字符串存在在seps数组

split(string, array [, fieldsep [, seps ] ]) 用定界符生成一个字符串列表,并将该列表存入数组
sprintf(format, expression1, ...) 打印
strtonum(str) 字符转转换成数字
sub(regexp, replacement [, target]) 将正则表达式匹配到的第一处内容替换成replacement
substr(string, start [, length]) 分割字符串,根据其实位置和长度
tolower(string) 转换成小写
toupper(string) 转换成大写

输入输出函数(Input/Output Functions)


函数


说明

close(filename [, how]) 关闭文件输入输出流
fflush([filename]) 刷新与文件名相关的任何缓冲输出
system(command) 执行操作系统命令,返回值给awk程序

时间函数(Time Functions)


函数


说明

mktime(datespec) datespec为时间戳格式,与systime()格式一样
strftime([format [, timestamp [, utc-flag]]]) 格式化timestamp的内容,返回日期格式
systime() 返回系统时间,精确到秒

位操作函数(Bit-Manipulation Functions)


函数


说明

and(v1, v2) v1,v2的与操作结果
compl(val) val的反码
lshift(val, count) 返回val左移count位的值
or(v1, v2) v1,v2的或操作
rshift(val, count) 返回val右移count位的值
xor(v1, v2) 返回v1,v2的异或的值

获取类型信息(Getting Type Information)


函数


说明

isarray(x) 如果x是数组,返回true.否则false

字符串转换函数(String-Translation Functions)


函数


说明

bindtextdomain(directory [, domain]) 设置awk要搜寻信息的目录和域
dcgettext(string [, domain [, category]]) 返回的字符串string 翻译文本域domain 的语言环境类别category
dcngettext(string1, string2, number [, domain [, category]])
返回string1和string2的翻译数量的复数形式,string1,string2在语言环境类别的文本域里

内置函数还有些高级特性,等许多实例,以后有机会补充。

 二. 自定义函数

格式入下:

代码如下:

function name([parameter-list])  
{  
  body-of-function  
}

如:

代码如下:

function myprint(num)  
{  
  printf "%6.3g\n", num  
}

awk这个命令还有很多功能,打算就只写这么多了。以后可能更多在一些例子里,与其他命令结合时会提到。

(0)

相关推荐

  • Linux shell下30个有趣的命令和提示(推荐)

    这些是我收集了多年的Linux shell的30个有趣的命令和提示. 1. 监控命令(每2秒运行一次) watch "ls -larth" 2. 使用一个端口杀死程序 sudo fuser -k 8000/tcp 3. 限制以下命令的内存使用 ulimit -Sv 1000 # 1000 KBs = 1 MB ulimit -Sv unlimited # Remove limit 4. 使用正则表达式重命名所选文件 rename 's/\.bak$/.txt/' *.bak 5. 获得

  • 一天一个shell命令 linux好管家-磁盘-du命令详解

    du命令 磁盘管理 du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的. 语法 du [选项][文件] 选项 -a或-all 显示目录中个别文件的大小. -b或-bytes 显示目录或文件大小时,以byte为单位. -c或--total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和. -k或--kilobytes 以KB(1024bytes)为单位输出. -m或--megabytes 以MB为单位

  • 一天一个shell命令 linux文件内容操作系列-cat命令详解

    注:在awk命令之后,没有太多复杂命令,都是一些基础命令. 说明: cat,是单词 concatenate 的缩写, 把文件的内容输出到stdout.当与重定向操作符 (> 或 >>结合使用时, 一般都是用来将多个文件连接起来. 用法: 1. $cat file1 file2 file3 2. 不仅可以从文件中读取内容并且拼接,还能从标准输入流中读取 例如:$echo 'some content' |  cat - file.txt 解释:这里的 - 就代表了 'some content

  • 一天一个shell命令 linux文本操作系列-tree命令详解

    tree命令是以图形化的树结构打印文件和目录的主角.通常linux发行版本中并没有包括这个命令.你需要用包管理器自行安装. 实例: 1. tree 打印当前目录下所有文件 2. tree –p ${dir} 打印dir目录下所有文件,以及他们的权限 3. tree –h ${dir} 打印dir目录下所有文件,以及适读的大小 4. tree path –P "*.sh" 打印所有.sh结尾的文件 5. tree path –H http://localhost –o out.html

  • 一天一个shell命令 linux文本内容操作系列-cut命令详解

    说明: cut 按列切分文件,你可以指定分隔每列的定界符.在cut的术语中,每列都是一个字段,就是有时候说第一列,可能表述称第一个字段. 实战: 假设有文件data.txt,格式如下 NO    Name    Mark    Percent  1    Sarath    45    90  2    Alex    49    98  3    Anu    45    90 分隔符(定界符)为Tab 制表符 如果我要取得第二列,所有人的名称,有什么好的办法吗?此时cut该大显身手了. 1.

  • 一天一个shell命令 linux文本内容操作系列-sed命令详解

    说明: sed是stream editor(流编辑器)的缩写.它能够完美匹配正则表达式.sed和awk是文件编辑最重要的两个命令了.尤其涉及到了很多正则表达式的问题,笔者不敢也有点犯怵,试着写写. 实例: 1.替换文件中的字符串 $sed -i 's/text/replace/g' file #如果不加g结尾,则替换每一行的第一个 #如果只是打印,去掉-i 2.忽略前N处匹配,从N+1出开始替换 $sed -i 's/text/replace/2g' file #在g前面加入数字N 3.移除空白

  • 一天一个shell命令 linux文本内容操作系列-grep命令详解

    从这篇开始,是文本内容操作,区别于文本操作. Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户. shell,perl,python,一直都是文本操作的专家语言,而我们今后学习的的将是shell的噱头--文本操作.下面提到最常见的一个: grep 这算是文本内容的一个重量级选手,能根据某些规格在上千行的文本文件中查找

  • 一天一个shell命令 linux好管家-进程-ps命令详解

    小知识(以ps为例): 查看命令路径  which ps 命令帮助 ps --help 命令完全手册: man ps 说明 ps全称是:Process Status (进程状态),他就是提供进程信息的. ps命令用于报告当前系统的进程状态.可以搭配kill指令随时中断.删除不必要的程序.ps命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态.进程是否结束.进程有没有僵死.哪些进程占用了过多的资源等等,总之大部分信息都是可以通过执行该命令得到的. 附知识说

  • 一天一个shell命令 linux文本内容操作系列-awk命令详解

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理. awk有3个不同版本: awk.nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本. awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母.实际上 AWK

  • Linux中的EXT系列文件系统格式详解

    Linux文件系统 常见的硬盘如上图所示,每个盘片分多个磁道,每个磁道分多个扇区,每个扇区512字节,是硬盘的最小存储单元,但是在操作系统层面会将多个扇区组成块(block),是操作系统存储数据的最小单元,通常是8个扇区组成4K字节的块. 对于Linux文件系统,需要考虑以下几点: 文件系统需要有严格的组织形式,使文件能够以块为单位存储 文件系统需要有索引区,方便查找一个文件分成的多个块存在了什么位置 如果有文件近期经常被读写,需要有缓存层 文件应该用文件夹的形式组织起来方便管理和查询 Linu

  • Linux下使用killall命令终止进程的8大用法实例详解

    Linux 的命令行提供很多命令来杀死进程.比如,你可以向 kill 命传递一个PID来杀死进程:pkill 命令使用一个正则表达式作为输入,所以和该模式匹配的进程都被杀死. 但是还有一个命令叫 killall ,默认情况下,它精确地匹配参数名,然后杀死匹配进程.在这篇文章中,我们将讨论有关这个命令的实际应用. 默认情况下,killall 命令将向一个/组进程发送一个 SIGTERM 信号,但是,也可以通过参数发送一个指定的信号. 下面我们通过例子详细介绍 killall 的 8 大用法. 1.

  • linux 编译安装python3.6的教程详解

    1. 首先去官网  https://www.python.org/downloads/source/ 下载 Gzipped source tarball 不要下载 " XZ compressed source tarball " ,目前 python3.6 最新版压缩包名字是:Python-3.6.7.tgz. 把下载的压缩包随便放到一个地方,也可以放到桌面(便于安装过后删除安装包和解压后的安装包). 2. 命令行切换到上面压缩文件所在的目录(比如桌面),然后输入 tar -xzf P

  • Linux下Makefile的编写与使用详解

    目录 Makefile Makefile文件命名和规则 Makefile的工作原理 Makefile变量 Makefile函数 Makefile clean规则 Makefile 一个工程文件中的源文件可能有很多,并且不同的功能.模块等都放在不同的目录中,常规的编译已经不能高效化的处理这样的问题,而Makefile就是为解决这一问题而来. Makefile一旦写好,只需一个make指令,即可完成Makefile文件中所编写的所有指令,从而编译整个工程文件,极大的提高了效率. make是一个命令工

  • Linux行处理工具之grep 正则表达式详解

    目录 正则表达式在grep应用以及差别 匹配案例 fgrep 总结 之前我们学习了linux grep的基本操作,以及提及了linux grep的孪生兄弟egrep 和 fgrep,这次我们来看下. 在介绍正则表达式之前,我们先来尝试一下,假如有如下文本. 我们想获取空行,应该如何来写呢? 命令: grep ^$ test1 -n 通过上述例子,我们使用正则表达式^$已经成功拿到了第四行数据,那么,这究竟如何解呢,我们细看博文. 正则表达式在grep应用以及差别 grep表达式有三种不同的版本,

随机推荐