awk可以接收文件和标准输入
awk 'BEGIN{ print "start" } /pattern/ { commands } END{ print "end" }' file
- 执行BEGIN { commands } 语句块中的语句,“BEGIN”需大写
- 从文件或stdin中读取一行,然后执行pattern { commands }。重复这个过程,直到文件全部被读取完毕。
- 当读至输入流末尾时,执行END { commands } 语句块,“END”需大写
- 中间部分默认执行{ print }
- pattern用于过滤匹配哪些行,没有提供样式那么awk就认为所有的行都是匹配的
- 当print的参数是以逗号进行分隔时,参数打印时则以空格作为定界符
简单例子:
$ echo -e "line1\nline2" | awk 'BEGIN{ print "Start" } { print } END{ print "End" } '
Start
line1
line2
End
awk变量
内部使用变量不需要$符号,加$符号表示打印第几列;另外内部变量也是字符串
内建变量
变量 | 描述 |
---|---|
FIELDWIDTH | 字段宽度,用于没有分隔符的情况,设置之后FS将不起作用 |
FS | 列分隔符(默认是空格) |
RS | 行分隔符(默认换行符) |
OFS | 输出的列分隔符(默认是空格) |
ORS | 输出的行分隔符(默认换行符) |
NR | 已读行数 |
FNR | 当前文件已读行数(当读取另一个文件时,FNR将被重置为1) |
NF | 字段总数 |
IGNORECASE | 是否忽略大小写 |
自定义变量
- 内部自定义变量
awk '{name="tuyou";print tuyou}'
- 命令行变量
awk -f script n=1 data.txt #这种命令行变量在BEGIN部分不可用
awk -v n=1 -f script data.txt #这种即可以BEGIN使用变量
awk -v name=tuyou '{print name}'
数组
awk的数组叫关联数组,也就是说数组的索引值可以是任意字符串。索引顺序可能和加入顺序不一致
定义数组
arrayName[index]=value
遍历数组
for (var in arrayName) {
}
删除数组元素
delete arrayName[index]
行过滤方式
正则表达式
awk '/pattern/{print $0}' #过滤出只有匹配正则表达式的行
匹配操作符
awk '$n ~ /pattern/{print $0}' #过滤出第n列匹配pattern的行
awk '$n !~ /pattern/{print $0}' #过滤出第n列不匹配pattern的行
数学表达式
awk '$n == 0{print $0}' #匹配出第n列等于0的行
分支语句
awk '{
if(condition){
}else if(condition){
}else{
}
}'
循环语句
awk '{
while(condition){
break; //支持break
continue; //支持continue
}
}'
awk '{
do{
break; //支持break
continue; //支持continue
}while(condition)
}'
awk '{
for (i = 0; i < n; i++) {
}
}'
格式化输出
awk '{printf "format string", x, y, z...}'
format格式
%[modifier]control-letter
控制字符 | 说明 |
---|---|
c | 将一个数字作为ascii字符显示 |
d | 显示一个整数值 |
i | 和d一样 |
s | 显示一个字符串 |
f | 显示一个浮点数 |
o | 显示八进制 |
x | 显示十六进制 |
X | 显示十六进制,字符大写表示 |
modifier
-width.prec
修饰字符 | 说明 |
---|---|
width | 指定最小宽度,小于用空格填充 |
prec | 指定小数的小数位长度,或者字符串的最大长度 |
- | 左对齐 |
内建函数
数学函数
函数 | 说明 |
---|---|
int(x) | 小数取整 |
exp(x) | 指数函数 |
log(x) | 自然对数 |
rand() | 0到1的随机数 |
srand(x) | 0到1的随机数,指定随机种子 |
sqrt(x) | 平方根 |
sin(x) | x的正弦,x以弧度为单位 |
cos(x) | x的余弦,x以弧度为单位 |
tan(x) | |
atan2(x,y) | x/y的反正切,x和y以弧度为单位 |
字符串函数
函数 | 说明 |
---|---|
asort(s [,d]) | 将数组s按数据元素值排序。索引值会被替换成表示新的排序顺序的连续数字。另外,如果指定了d,则排序后的数组会存储在数组d中 |
asorti(s [,d]) | 将数组s按索引值排序。生成的数组会将索引值作为数据元素值,用连续数字索引来表 明排序顺序。另外如果指定了d,排序后的数组会存储在数组d中 |
gensub(r, s, h [, t]) | 查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果h是一个以g 或G开头的字符串,就用s替换掉匹配的文本。如果h是一个数字,它表示要替换掉第h 处r匹配的地方 |
gsub(r, s [,t]) | 查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果找到了,就 全部替换成字符串s |
index(s, t) | 返回字符串t在字符串s中的索引值,如果没找到的话返回0 |
length([s]) | 返回字符串s的长度;如果没有指定的话,返回$0的长度 |
match(s, r [,a]) | 返回字符串s中正则表达式r出现位置的索引。如果指定了数组a,它会存储s中匹配正 则表达式的那部分 |
split(s, a [,r]) | 将s用FS字符或正则表达式r(如果指定了的话)分开放到数组a中。返回字段的总数 |
sprintf(format,variables) | 用提供的format和variables返回一个类似于printf输出的字符串 |
sub(r, s [,t]) | 在变量$0或目标字符串t中查找正则表达式r的匹配。如果找到了,就用字符串s替换 掉第一处匹配 |
substr(s, i [,n]) | 返回s中从索引值i开始的n个字符组成的子字符串。如果未提供n,则返回s剩下的部 分 |
tolower(s) | 将s中的所有字符转换成小写 |
toupper(s) | 将s中的所有字符转换成大写 |
时间函数
函数 | 说明 |
---|---|
mktime(datespec) | 将一个按YYYY MM DD HH MM SS [DST]格式指定的日期转换成时间戳值 |
strftime(format[,timestamp]) | 将当前时间的时间戳或timestamp格式化(采用shell函数date()的格式) |
systime( ) | 返回当前时间的时间戳 |
自定义函数
function name([variables]) {
statements
return value
}
定义函数时,它必须出现在所有代码块之前(包括BEGIN代码块)
gawk '
> function myprint()
>{
> printf "%-16s - %s\n", $1, $4
>}
> BEGIN{FS="\n"; RS=""}
>{
> myprint()
> }' data2
创建函数库
$ cat funclib
function myprint()
{
printf "%-16s - %s\n", $1, $4
}
function myrand(limit)
{
return int(limit * rand())
}
function printthird()
{
print $3
}
$ cat script4
BEGIN{ FS="\n"; RS=""}
{
myprint()
}
$ gawk -f funclib -f script4 data.txt