awk所有常用语法
awk [OPTIONS] PROGRAM FILE...
选项:
-F 指定分隔符
-f 引用awk脚本
-v VAR=VALUE 定义一个变量传递给PROGRAM,但是这里的变量BEGIN读不了,只有PROGRAM和END才能读。
PROGRAM由“ PATTERNS{ACTION;ACTION...} ”组成
PATTERNS和ACTION可以其中一个不写
PATTERNS不写表示所有记录。
ACTION不写默认为print $0
记录(record)和字段(filed):
记录是根据RS变量的值分割,默认情况下是换行符,也就是一行就是一个记录。
字段是根据FS变量的值定义的,用于分割记录成字段。
引用记录的字段:
$0 代表整个记录
$1 第一个字段
$N 第N个字段
AWK的变量:
1、内建变量,由AWK自身内置的一些变量。
FILENAME: 文件名。
FS:字段分隔符,默认是空格和制表符。
OFS:每个字段默认的输出分割符号。
RS:记录分隔符,默认是换行符。
ORS:每个记录默认的输出分割符号。
NR:当前记录所在的行号(多个文件时会重置行号)
FNR:当多个文件时不会重置行号。
NF:当即字段的段号。
IGNORECASE:匹配时是否忽略大小写。
RLENGTH:由match函数所匹配到的子字符串的长度。
RSTART:由match函数所匹配到的子字符串的起始位置
2、用户自定义变量
·通过”awk -v 变量名=变量值“ 定义并使用。
·在ACTION内部直接定义。
变量的值可以使用0开头表示8进制,0x开头表示16进制。
使用变量:
不管时内建变量还是用户自定义变量,直接写变量名即可,不需要加”$“符号来引用变量。
但是for循环内的变量需要加”$“来引用。
PATTERNS: 用于对判断是否对当前记录应用ACTION
这里的PATTERN不单单可以使用正则表达式,还可以是条件判断等。
具体如下:
1、/正则表达式/
2、/正则/ && /正则/
3、/正则/ || /正则/
4、PATTERN ? PATTERN : PATTERN #(三元运算符)
5、!PATTERN # 取反
6、PATTERN,PATTERN # 多个PATTERN
7、BEGIN
8、END
9、 匹配操作符
~ PATTERN 匹配指定正则表达式
!~ PATTERN 不匹配指定正则表达式
10、算数运算符
++ --
+= -= *= /= %=
+ - * / %
11、逻辑运算
&&
||
!
awk -F: '$1~/^r/ && $3>1000{print $0}' /etc/passwd
12、(PATTERN) 优先计算括号内的表达式
如: awk -F: '!($3>1000){print $1,$3}'
ACTION:
print ITEM,ITEM... : # 打印文本,ITEM之间默认用OFS变量的值隔开输出。
print ITME,ITEM... >file # 打印文本并覆盖重定向到file。
print ITME,ITEM... >>file # 打印文本并追加重定向到file。
printf("format",ITEM,ITEM...) [>file] : # 格式化打印文本。
printf("format",ITEM,ITEM...) [>>file] # 格式化打印文本并追加重定向到file。
format的组成:
%[修饰符号]控制字母
控制字母:
s 字符串
d 或 i 整数型
f 浮点数
o 八进制
x 十六进制
修饰符号:
width: 指定输出的长度,不足则使用空格填充,如果超过指定长度则按实际长度输出。
- : 左对齐
.prec : prec时具体小数点的位数,会四舍五入。
如:awk -v NUM=2.2356 'BEGIN{printf("%.2f",NUM)}'
AWK的数组:
AWK的数组本质上都是关联数组,虽然你可以使用0123这类数字,看上去也很想index类型数组。但是本质还是关联数组。
定义数组:
变量名[INDEX]=VALUE
INDEX: 可以是整数,也可以是字符串。
arr["name"]="zhangsan"
arr[2]=88
arr["age"]=18
引用数组:
数组名[index]
判断数组是否存在元素:
if ( index in 数组变量名)
arr["name"]="zhangsan"
if( "name" in arr){
print(arr["name"])
}
遍历数组:#使用特殊的for循环进行遍历
# for循环遍历出来的是数组中的index,而不是数组index对应的值。这点和bash的数组不一样,但是和javascript一样。
for(变量名 in 数组变量名){
print(数组变量名[变量名])
}
删除数组:
delete 数组变量名[index] # 删除数组的某个元素
delete 数组变量名 # 删除整个数组
结构化语句if:
# 只有if时可以写在同一行,并不写花括号
if(condition) statement1
# 但是如果由else就必须写花括号
if(condition){
statement1
}[else{
statement2
}]
结构化语句while和do while:
while(condition){
statements
}
do{
statements
}while(condition)
结构化语句for循环:
for(变量;条件;自增){
#for循环内部引用循环内局部变量要使用$
}
循环控制break和continue:
break:跳出循环
continue:结束当前此次循环二进入下一次循环
控制语句exit:
exit 是用来结束awk自身的循环,如果有些END{}语句则处理END语句,没有就结束了。
控制语句next:
next 使awk自身循环提前结束对本行的处理而直接进入下一行。
awk -F: '{if($3%2!=0){next}; print $1,$3}' /etc/passwd
# AWK函数:
数学函数:
int(x) 对X进行floor运算。(地板)
sqrt(x) X的平方根
随机数函数:
srand([x]) 生产随机数种子
rand() 返回随机数,0-1之间。
字符串函数:
length([str]) #返回给定字符串的长度,如果没有参数则返回$0的长度
index(str,T) #返回T在str中第一次出现的index位置。
match(str,regex[,A]) # 返回str中匹配正则表达式regex出现的index位置。如果指定了数组A,会将匹配的部分存储进去。
sub(regex,replace[,T]) # 如果指定了T则在T中根据正则regex查找第一次匹配的字符串并替换为replace,否则在$0中查找并替换。
gsub(regex,replace[,T]) # 和上面的唯一不同是,将匹配的所有字符串都会替换。
substr(str,i[,number]) # 返回字符串s从出现第一个i到number之间的字符串,如果没有number则为字符串S的尾部。
split(str,arr[,regex]) # 根据FS变量或正则regex(如果指定了的话)分割字符串s并存储到数组a中。
sprintf(format,variables) # 根据给定的variables和format来返回一个类似printf的字符串。
tolower(str) # 转换为小写
toupper(str) # 转换为大写
数组排序和判断:(自然排序)
asort(arr [,dest_arr]) #将arr的值进行排序,然后将index重置为1、2、3形式,如果指定了dest_arr则保存到dest_arr中,否则会改变原arr。
asorti(arr [,dest_arr]) # 根据arr的index进行排序,并保存到dest_arr中(如果指定了,否则会改变原arr)
isarray(arr) # 判断给定的变量是否为数组类型
时间函数:
mktime(datestr) # 将给定的datestr(YYYY MM DD HH MM SS [DST])转换为时间戳
strftime(format [,timespamp]) # 将当前时间或给定的timestamp转换为日期。
systime() # 返回当前时间的时间戳。
#自定义函数,必须写在BEGIN{}之前
function 函数名([参数名]){
[return xxx]
}
AWK 中I/O操作的语句:
getline的用法:
geline会返回下面的值:
1 如果还有下一行可以读取
0 文件的尾部
-1 表示出现错误,可以打印ERRNO查看出错的详细内容。
getline #读取用户输出文本存储到$0
getline <file #读取file用作下一个记录
awk 'BEGIN{print "请输入姓名";getline input<"-";print input}'
getline var #读取awk自身循环的下一行记录并赋值给var
awk -F: '{getline str;print str}' /etc/passwd #你会发现passwd文件的第一行并没有打印。
getline var <file #读取file的每一行并赋值给var
command | getline [var] # 将shell命令的标准输出保存到$0或者给定的var变量中。
awk -F: 'BEGIN{"id root"|getline;print}'
fflush([file]) 刷新与打开的输出文件或管道文件相关联的任何缓冲区。如果文件丢失或为空字符串,则刷新所有打开的输出文件和管道。
system("命令")函数
运行给定的命令,如果命令会自动打印输出awk也会输出,不需要特意去print,然后该函数返回运行命令的退出状态$?。
awk 'BEGIN{var=system("id -un root");print var}'
print和printf有关IO重定向的用法:
print ... >> file
print ... > file
print ... | command
awk -F: 'BEGIN{print "fuck" | "cat &> /tmp/aa.txt"}'
printf也是类似的。
特殊文件:
/dev/stdin
/dev/stderr
/dev/stdout
/dev/fd/N
用法示例:
将print打印出错误
awk 'BEGIN{print "fuck" > "/dev/strerr"}'
本文来自博客园,作者:蕝戀,转载请注明原文链接:https://www.cnblogs.com/juelian/p/14532983.html