awk学习笔记

Usage: nawk [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]
program = pattern { action } | pattern | { action }
如果模式匹配,则执行操作 | 如果模式匹配,则打印记录 | 针对每条记录,执行操作

变量名区分大小写,要匹配表达式[A-Za-z_][A-Za-z_0-9]*
内建变量
FILENAME  当前输入文件的名字
FNR  当前输入文件的记录数
NR  在工作中的记录数
NF  当前记录的字段数,$1,$2...$NF表示各字段,$0引用当前记录
FS  输入字段分隔符,可以是正则表达式,默认为空格,例如nawk -v FS=":+"
RS  输入记录分隔字符,默认为换行(\n),例如nawk -v RS=":"
OFS   输出字段分隔符,默认为空格
ORS   输出记录分隔符,默认为换行(\n)
ARGC  参数计数, -v和-f选项的参数不可用
ARGV  参数数组,ARGV[0],...,ARGV[ARGC-1];ARGV[0]是awk程序本身
ENVIRON  访问环境变量的内建数组, ENVIRON["HOME"]
SUBSEP 数组下标分隔符,默认为"\034".awk会把索引列表中的逗号转化为SUBSEP.
       如果逗号本身出现在数组索引值中,可以直接用SUBSEP作为分隔符。

字符串拼接
s = "ABCD"
s = "AB" "CD"
s = "A" "B" "C" "D"
以上结果等同

awk里的数字都是双精度的浮点数
数字转字符 n=123; s="" n
字符转数字 s="123"; n=0+s

有两种特殊模式,
BEGIN 与此模式匹配的操作在任何命令被执行之前执行,只被执行一次
END 与此模式匹配的操作在所有处理结束后执行,只被执行一次

模式支持ERE(extended regular expression)
正则表达式用引号或者斜杠加以定界,~匹配 !~不匹配
例如 "ABC" ~ /^[A-Z]+$/ 结果为真
如果模式是一个正则表达式,表示它与整个输入记录匹配,等于$0 ~ /regexp/
模式可以是逗号隔开的两个表达式来表达一个范围,例如
(FNR==3),(FNR==5)
/[A-Z]/,/[0-9]/

1) 模拟wc命令
nawk '{C+=length($0)+1; W+=NF} END {print NR, W, C}' testfile

2) 文件大小总和
ls -l | nawk -v COLUMN=5 '{sum+=$COLUMN} END {print sum}'

3) 查找文件
egrep 'string1|string2' testfile
nawk '/string1|string2/' testfile
nawk '/string1|string2/ {print FILENAME ":" FNR ":" $0}' testfile

4) 改变输出字段分隔符
echo "one:two:three:four" | nawk -v FS=":" -v OFS="\n" '{print $1,$2,$3,$4}'
echo "one:two:three:four" | nawk '{FS=":"; OFS="\n"; print $1,$2,$3,$4}'
echo "one:two:three:four" | nawk '{FS=":"; OFS="\n"; $1=$1; print $0}'
(更新某个字段,实际上没变,强制用新的分隔符重新组合记录)

5) 输出文件的3-5行
nawk '(FNR==3),(FNR==5) {print $0}' testfile

6) 模拟uniq命令
sort testfile | uniq
sort testfile | nawk 'last != $0 {print $0; last=$0}'

7) 条件语句
if (exp1)
    statement1
else if (exp2)
    statement2
...
else
    statement

对于数组成员的测试
if (key in array)
if !(key in array)
if ((key1, key2, key3) in array)

8) 重复执行
while (exp)
    statement

do
    statement
while (exp)

for (exp1; exp2; exp3)
    statement
   
for (key in array)
    statement
*对于多维数组,使用split(key, keyarray, SUBSEP)把各个index放到keyarray里面
支持break和continue语句

9) 流程控制语句
next 针对此记录跳过更进一步的模式检查
nextfile 针对此文件跳过更进一步的模式检查
  如果不支持可以用如下方式模拟
  在程序开始处添加
  FNR==1 {SKIPFILE=""}
  FILENAME==SKIPFILE {next}
  在需要的地方用如下语句取代nextfile
  SKIPFILE=FILENAME; next 
exit n 退出返回n

10) getline用法
getline 从当前输入文件中,读取下条记录存入$0,并更新NF,NR,FNR
getline var 从当前输入文件中,读取下条记录存入var,并更新NR,FNR
getline < file 从文件中,读取下条记录存入$0,并更新NF
getline var < file 从文件中,读取下条记录存入var
cmd | getline 从外部命令cmd读取下条记录存入$0,并更新NF
cmd | getline var 从外部命令cmd读取下条记录存入var
成功读取返回1,文件末尾返回0,读取失败返回-1
例如,
从终端读入 getline answer < "/dev/tty"

11) 命令管道
command="cat /etc/passwd"
while ((command | getline) > 0)
        print $0 | "sort"
close(command)
close("sort")
使用完后可以使用close()进行关闭

12) 重定向输出
print "hello" > file
完成后使用close(file)关闭文件释放资源
避免没有使用close()情况下,混用>和>>到同一个文件。

13) system()函数调用外部程序
返回值为外部程序的返回码

14) 函数
变量为传值,数组为传引用。内置函数如下
length(string) 字符串中的字符个数
substr(string,start,len) 返回string的start(1开始编号)字符开始,len个字符的子串
    len可以省略,省略时返回start开始的剩余部分
totower(string) 转为小写字符
toupper(string) 转为大写字符
index(string,find) 查找string中是否有find,返回find子串的起始位置,找不到返回0
match(string,reg) 将string与正则表达式reg匹配,如果匹配返回匹配的位置,否则返回0
    如果匹配,全局变量RSTART设置为string中开始匹配字符位置,
RLENGTH设置为匹配的字符串长度,即匹配字符串为substr(string,RSTART,RLENGTH)
sub(reg,replacement,target) 将target与reg匹配,最左边最长的匹配部分替换为replacement.
gsub(reg,replacement,target) 类似sub,不过替换所有匹配字符串.返回替换数目.
    sub和gsub的一些说明:
返回替换数目;
会修改参数target;
如果省略参数target,默认为当前记录$0;
replacement里面的&会被替换为target中与reg匹配的字符串,
    如果不想替换则使用\&(在引号字符串中使用"\\&");
split(string,array,reg) 根据分界符reg,切割string并存储到array数组
printf(format,variable1,variable2...) 格式化输出,按format提供的格式输出变量
sprintf(format,variable1,variable2...) 返回已经格式化的字符串
内建变量OFMT控制浮点数字的输出格式,默认为 %.6g

15) 数学函数
atan(x,y) y/x的余切(弧度)
sin(x) x的正弦(弧度)
cos(x) x的余弦(弧度)
exp(x) e的x幂
log(x) x的自然对数值
sqrt(x) x的平方根
int(x) x的整数部分
rand() 随机数[0,1)
srand(x) 设置随机数发生器的种子,如果忽略x,则使用当前时间

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值