(一) 初识:
Awk 有三个版本awk、nawk和gawk. 一般是指gawk, linux是链接到gawk。
语法描述:
awk '{pattern + action}' {filenames}
三种调用方式, 首先掌握命令行方式即可。
1.命令行方式
awk [-F field-separator] 'commands' input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。
2.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk
3.将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。
先测试一个最简单的应用.
$export PS1='fxb$';
fxb$cat abcd.log
111 aaa adfsk
2222 bbb skeioskls
33 cccc slweoklsdoi
44 ddddd slkwoelksl
只显示第2列,
fxb$cat abcd.log|awk '{print $2}'
aaa
bbb
cccc
ddddd
也可以用fxb$awk '{print $2}' abcd.log, 效果一样, 不过一般还是习惯用管道符号
这个就是最简单的应用, 没有指定分隔符, 因为是默认是空格, 也没有指定pattern, 只是用了action.
在来看看使用pattern 的简单例子:
找到匹配222的行, 然后输出整行
fxb$cat abcd.log|awk '/222/{print $0}'
2222 bbb skeioskls
fxb$cat abcd.log|awk '/222/'
2222 bbb skeioskls
这里看到print $0 效果一样.
这里‘/ /’表示其间是正则表达式, 而$0代表整行.
l 关于正则表达式, 见正则表达式学习总结.
通过这两个例子, 来说明一下awk的工作原理 :
awk 逐行扫描文件, 从第一行开始到最后一行. 并与模式想匹配, 如果匹配上, 就执行特定的操作. 如果没有指定模式, 就是所有行, 如果没有指定操作, 则显示整行。
接下来就要详细了解 awk中模式和操作, 以及awk中的变量。
(一) 模式部分:
模式可以有:
l /正则表达式/:使用通配符的扩展集。包括模式匹配表达式, 也就是使用用运算符~(匹配)和~!(不匹配)。
l 关系表达式模式
l 范围模式:使用成对模式来获取一个范围,从某一行到另一行。
l BEGIN/END: 指定开始或者结尾的规则
l BEGINFILE/ENDFILE: Two special patterns for advanced control.
l Empty: The empty pattern, which matches every record.
1. 关于正则表达式
使用/regexp / 符号来表示使用了正则表达式,
Note: 这里不重复正则表达式部分的内容, 具体参考正则表达式的学习内容
但关于awk 正则表达式,还有下面的内容: ,学习
l 动态正则表达式 ,
什么是动态正则, 有什么用.
以下类容, 来至网络..(关于动态正则,暂时先了解这么多)
‘~’和’!~’操作的右边不一定是一个常量正则表达式(字符串在‘//’之间,比如’/pattern/’),它可以使任何表达式,这个表达式被计算和转换成一个字符串,在有必要的情况下,这个字符串的内容被用作正则表达式,用这种方式计算的正则表达式叫做动态正则表达式(动态正则),例如:
BEGIN { identifier_regexp = "[A-Za-z_][A-Za-z_0-9]+" } #无’//’ $0 ~ identifier_regexp { print }设置identifier_regexp为一个正则表达式,使用awk变量在存储,然后测试输入的记录是否匹配这个正则表达式。 注意:当使用‘~’和’!~’操作的时候,使用’//’的常量正则表达式和使用双引号的字符串常量有一点不同,如果你要使用字符串常量,你必须懂得字符串实际上市被扫描了两次,第一次是awk读取你的程序的时候,第二次是使用操作右边的模式匹配左边的字符串的时候,这是任何字符串值的表达式(例如上面的identifier_regexp,为一个变量表达式),不仅仅是常量字符串。
如果字符串被扫描两次,它有什么不同呢?答案是必须做转义序列,特别是使用反斜杠,为了在字符串的正则表达式里面获取一个反斜杠,你必须键入两个反斜杠。
例如:/\*/是一个为了匹配字面意义的’*’常量正则表达式,仅使用一个反斜杠,为了在字符串中做同样的事情,你必须键入”\\*”,第一个反斜杠转义第二个反斜杠,视为了让字符串包含两个字符’\’和’*’,明确来说就是为了避免让shell进行元字符扩展。
你也可以在match函数中使用动态正则表达式,其余gsub,sub,gensub,未测试,建议最好使用常量正则表达式。
awk自己专用的正则表达式,注意学习:
\s
Matches any whitespace character. Think of it as shorthand for ‘[[:space:]]’.
\S
Matches any character that is not whitespace. Think of it as shorthand for ‘[^[:space:]]’.
\w
Matches any word-constituent character—that is, it matches any letter, digit, or underscore. Think of it as shorthand for ‘[[:alnum:]_]’.
\W
Matches any character that is not word-constituent. Think of it as shorthand for ‘[^[:alnum:]_]’.
\<
Matches the empty string at the beginning of a word. For example, /\<away/ matches ‘away’ but not ‘stowaway’.
\>
Matches the empty string at the end of a word. For example, /stow\>/ matches ‘stow’ but not ‘stowaway’.
Matches the empty string at either the beginning or the end of a word (i.e., the word boundary). For example, ‘\yballs?\y’ matches either ‘ball’ or ‘balls’, as a separate word.
\B
Matches the empty string that occurs between two word-constituent characters. For example, /\Brat\B/ matches ‘crate’, but it does not match ‘dirty rat’. ‘\B’ is essentially the opposite of ‘\y’.
There are two other operators that work on buffers. In Emacs, a buffer is, naturally, an Emacs buffer. Other GNU programs, including gawk, consider the entire string to match as the buffer. The operators are:
\`
Matches the empty string at the beginning of a buffer (string)
Matches the empty string at the end of a buffer (string)
Escape Sequences 转义序列,
两种;
1) 使用反斜杠 (backslash ),‘\’ 来作为转义
2) 其它的转义序列, 来表示不能打印的字符,例如TAB.
‘\’ 作为转义的列子
$ awk 'BEGIN { print "a" }'
a
---- 普通的输出
$ awk '