awk是一个文本处理工具,通常用于处理数据和生成结果报告。它以三位创始人的姓名首字母命名:AlfredAho、PeterWeinberger和BrianKernighan。语法:awk[options]'BEGIN{}pattern{commands}END{}'awk[options]'BEGIN{}pattern{commands}END{}'说明:optionsoptionBEGIN{}在正式处理数据之前执行模式匹配Mode{commands;...}处理命令,可能多行END{}处理后执行所有匹配的数据内置变量变量名说明$0整行的内容$1-$n当前行的第n个字段(列)NFNumber字段,该字段的个数currentrow(多少列)NRNumberRow,当前行的行号,从1到FNRFileNumberRow,处理多个文件时,每个文件的行号单独统计,都是从0开始FSField分隔符,输入字段分隔符(默认空格或tab键)RSRowSeparator,输入行分隔符(默认回车换行)OFSOutputFieldSeparator,输出字段分隔符(默认空格)ORSOutputRowSeparator,输出行分隔符(默认回车换行)FILENAME当前输入的文件名ARGC命令行参数个数ARGV命令行参数数组例子:#用:分隔,输出第一列?awk'BEGIN{FS=":"}{print$1}'/etc/passwd#用-分隔行-andcolumnswith:,outputcolumns1and2?awk'BEGIN{FS=":";RS="--"}{print$1,$2}'/etc/passwd#用:分隔列并输出最后一个列,因为NF变量是总列数?awk'BEGIN{FS=":"}{print$NF}'/etc/passwd格式化输出(printf)格式说明符描述修饰符描述%s字符串-左对齐%d十进制+右对齐%f浮点数#八进制前加0,十六进制前加0x%o八进制%e科学计数法%c单数字符的ASCII码示例:#printf"%+20s%-20s\n",$1,$7#-左对齐;+右对齐#20列宽,不足补空#sprintstring#.3fprintreserved3浮点数位数?awk'BEGIN{FS=":";OFS="-"}{printf"%+20s%20.3f%-20s\n",$1,$3,$7}'/etc/passwdroot0.000/bin/bashbin1.000/sbin/nologindaemon2.000/sbin/nologinadm3.000/sbin/nologinlp4.000/sbin/nologin模式匹配(pattern)RegExp:/pattern/Relationaloperations:<,>,<=,>=,==,!=,~正则匹配,!~非正则匹配,&&与,||/etc/passwdroot:x:0:0:root:/root:/bin/bash#打印第三列大于1000的行?awk'BEGIN{FS=":"}$3>1000{print$0}'/etc/passwdnfsnobody:x:65534:65534:AnonymousNFSUser:/var/lib/nfs:/sbin/nologin#打印第7列为/sbin/nologin的行?awk'BEGIN{FS=":"}$7=="/sbin/nologin"{print$0}'/etc/passwdbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologin#打印以nologin结尾的7行?awk'BEGIN{FS=":"}$7~/.*nologin$/{print$0}'/etc/passwdbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologin#打印第三列大于500且第七列以nologin结尾的行?awk'BEGIN{FS=":"}$3>500&&$7~/.*nologin$/{print$0}'/etc/passwdchrony:x:997:995::/var/lib/chrony:/sbin/nologindockerroot:x:996:993:Docker用户:/var/lib/docker:/sbin/nologin计算表达式示例:#数学计算?awk'BEGIN{x=10;y=2;打印x+y}'12?awk'BEGIN{x=10;y=2;打印x*y}'20?awk'BEGIN{x=10;y=2;打印x^y}'100?awk'BEGIN{x=10;y=2;打印x**y}'100?awk'BEGIN{x=10;y=x++;打印x,y}'1110?awk'BEGIN{x=10;y=++x;printx,y}'1111#打印空行号,统计空行数?awk'BEGIN{idx=0;}/^$/{idx++;printNR}END{printidx;}'/etc/passwd流控语句语法:#条件判断if(condition1){#dosomething}elseif(condition2){#dosomething}else{#dosomething}#loopwhile(condition){#dosomething}do#dosomethingwhile(condition)for(i=0;i<10;i++){#dosomething}例子:#如果第三列小于10,第七列是/sbin/nologin,printthisisif#如果第三列大于500,printthisiselseif#否则打印thisiselse?awk'BEGIN{FS=":"}{if($3<10&&$7="/sbin/nologin"){print"thisisif"}elseif($3>500){print"thisiselseif"}else{print"thisiselse"}}'/etc/passwdthisisifthisisifthisiselsethisiselseifthisiselse#计算1-10相加的结果#注意:变量不需要提前声明?awk'BEGIN{while(i<10){sum+=i;我++};printsum}'45?awk'BEGIN{do{sum+=i;我++;}while(i<10);printsum}'45?awk'BEGIN{for(i=0;i<10;i++){sum+=i;};printsum}'45string函数函数名说明返回值length(str)计算字符串长度整数长度值index(str,sub_str)in查找str中sub_str的位置索引,从1开始计数到lower(str)tolowercase转换成小写字符串toupper(str)tolargeconverteduppercasestringsubstr(str,start,length)fromstrstart字符开头,截取长度数字到子串split(str,arr,fs)根据fs拆分字符串,并将结果保存在arr中拆分后的子串个数match(str,reg)根据reg在str中查找,返回positionindexpositionsub(reg,new_sub_str,str)在str中查找匹配reg的子串,替换为new_sub_str,仅replaces第一个替换的个数gsub(reg,new_sub_str,str)类似于sub,replaces所有替换个数的例子:#sub(/oo/,"11",$1)返回替换个数;下面的$1是替换后的值?awk'BEGIN{FS=":"}{printlength($1),toupper($1),substr($1,0,2),sub(/oo/,"11",$1),$1}'/etc/passwd4ROOTro1r11t3BINbi0bin6DAEMONda0daemon4SYNCsy0sync#数组下标从1开始?awk'BEGIN{str="Shell;Python;C;C++;Java;PHP";拆分(str,arr,“;”);printarr[2]}'Python?awk'BEGIN{str="Shell;Python;C;C++;Java;PHP";split(str,arr,";");for(iinarr){打印arr[i];}}'C++JavaPHSHellPythonC常用选项(options)-v参数传递-f指定脚本文件-v指定分隔符号-V查看awk版本例子:#importexternalvariables?var1=10?var2="helloawk"?awk-vvar1="$var1"-vvar2="$var2"'BEGIN{printvar1,var2}'10helloawk#将所有操作提取到一个单独的文件中#建议:复杂操作优先使用此方法,这更容易理解和管理程序?touchscript.awkBEGIN{FS=":"}{if($3<10&&$7="/sbin/nologin"){print"thisisif"}elseif($3>500){print"thisiselseif"}else{print"thisiselse"}}?awk-fscript.awk/etc/passwd#-F:相当于BEGIN{FS=":"}$awk-F:'{print$1}'pwdrootbindaemon数组shell中的数组操作如下:操作示例输出定义一个数组arr=("Python""PHP""Java""Go""Rust")一个数组元素(下标从0开始)echo${arr[2]}Java数组元素个数echo${#arr[@]}5一个元素的长度echo${#arr[0]}6修改元素值arr[2]="JAVA"删除数组元素unsetarr[1]打印所有数组元素)echo${arr[@]}PythonJAVAGoRust切片访问echo${arr[@]:0:2}PythonJAVA数组元素替换(第一次找到)echo${arr[@]/A/a}PythonJavaGoRust数组元素替换(全部)echo${arr[@]//A/a}PythonJaVaGoRust数组遍历forain${arr[*]};做echo$a;donewhilearraysareusedslightlydifferentlyinawk,它使用关联数组提供数组功能,即数组的索引可以是数字或任何字符串示例语法:#define#语法:array_name[index]=value?awk'BEGIN{arr[0]=0;arr["第二个"]="2";打印arr[0],arr["秒"];}'02#数组元素参与计算?awk'BEGIN{arr[0]=0;arr["第二个"]="2";printarr[0]+3,arr["second"];}'32#删除数组元素#语法:deletearray_name[index]?awk'BEGIN{arr[0]=0;arr["second"]=“2”;删除arr["second"];printarr["second"];}'#遍历数组#方法一:for...in是无序输出?awk'BEGIN{str="PythonRustPHPGo";arrLen=拆分(str,arr,“”);for(iinarr){printi,arr[i]}}'4Go1Python2Rust3PHP#方法二:for(i=1;i<=len;i++){...}有序输出?awk'BEGIN{str="PythonRustPHPGo";arrLen=拆分(str,arr,“”);for(i=1;i<=arrLen;i++){printi,arr[i]}}'1Rust2Go3Python4PHP
