欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

awk用法

程序员文章站 2022-05-31 10:06:16
...

awk用法

通用格式:awk 'pattern {action}'  file
 

                cmd | awk 'pattern {action}'

如果没有pattern,则对所有行都采用action,如果没有action,则打印匹配行。在pattern中可以使用各种定义的变量$0,,NF,NR等.
 

工作原理:awk 扫描一行,放入变量$0中,然后行被分隔成各个域,以指定的分隔符进行分离,默认为空格,可以通过参数FS指定。各个域都存于变量$i中,至多100个域。
 

awk -F : '{print $1}'  /etc/passwd         打印所有用户名
 

格式化输出:
 
print 支持使用转义字符,及OFMT变量定义的输出数字格式
awk '/Sally/{print "/t/tHave a nice day, " $1, $2 "/!"}' employees
awk 'BEGIN{OFMT="%.2f"; print 1.2456789, 12E 2}'
printf支持C语言同名函数的所有功能
echo "UNIX" | awk ' {printf "|%-15s|/n", $1}'
awk '{printf "The name is: %-15s ID is %8d/n", $1, $3}' employees
域分隔符:
awk F'[ :/t]' '{print $1, $2, $3}' employees

pattern
 :

模式可以是以下任意一个:
 

(1)   /正则表达式/:使用通配符的扩展集。
 

(2)   关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。
 

模式匹配表达式:用运算符~(匹配)和~!(不匹配)。用来在记录或者域内匹配正则表达式。如$ awk '$1 ~/^root/' test将显示test文件第一列中以root开头的行。
 

BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
 

END:让用户在最后一条输入记录被读取之后发生的动作。
 

Action
 
{}中的Action的极其类似C语言的子句,里面可以嵌套子句,可以使用条件、循环、支持变量函数定义、使用自定义或内部变量、内部函数,调用系统命令,输入输出重定向等强大的能力。
变量:var=value,若变量没有初始化,字符串为"",数字为0。
awk '$1 ~ /Tom/ {wage = $2 * $3; print wage}' filename
内置变量:
ARGC                 Number of command-line argument
ARGIND               Index in ARGV of the current file being processed from the command line (awk only)
ARGV                 Array of command-line arguments
CONVFMT              Conversion format for numbers, %.6g, by default (awk only)
ENVIRON              An array containing the values of the current environment variables passed in from the shell
ERRNO                Contains a string describing a system error occurring from redirection when reading from the getline function or when using the close function (awk only)
FIELDWIDTHS          A whitespace-separated list of fieldwidths used instead of FS when splitting records of fixed fieldwidth (awk only)
FILENAME             Name of current input file
FNR                  Record number in current file
FS                   The input field separator, by default a space
IGNORECASE           Turns off case sensitivity in regular expressions and string operations (awk only)
NF                当前记录的域个数,$NF可以引用到最后一个域
NR                   当前的记录序号
OFMT                 Output format for numbers
OFS                  Output field separator
ORS                  Output record separator
RLENGTH              Length of string matched by match function
R S                   Input record separator
RSTART               Offset of string matched by match function
RT                   The record terminator; awk sets it to the input text that matched the character or regex specified by RS
SUBSEP               Subscript separator
BEGIN模式后跟的ACTION,表示在awk处理文本以前进行的动作,可以用来初始化各种内部变量,或其他动作。
END  模式后跟的ACTION,表示在awk处理结束后进行的动作。
重定向:
awk '$4 >= 70 {print $1, $2 > "passing_file" }' filename
awk 'BEGIN{while("ls" | getline) print}'
条件语句
{if ( $3 > 89 && $3 < 101 ) Agrade++
 else if ( $3 > 79 ) Bgrade++
 else if ( $3 > 69 ) Cgrade++
 else if ( $3 > 59 ) Dgrade++
 else Fgrade++
}
循环:支持while,for的的标准循环结构及break,continue等。
{
for ( x = 3; x <= NF; x++ )
if ( $x == 0 ) { print "Get next item"; continue}
}
数组:awk的数组是map类型的,索引可以是数字也可是字符串。同时支持多维数组。
awk '{id[NR]=$3};END{for(x = 1; x <= NR; x++) print id[x]}' employees
awk '/^Tom/{name[NR]=$1};END{for(i in name){print name[i]}}' db
awk '{count[$2]++}END{for(name in count)print name,count[name] }' datafile4
split(string,array,FS)  按照分隔符FS将string分成多个域放在array中。

内置函数:
 
(g)sub(regx,string,[tstring])   (在tstring位置处)将regx的第一次(全部)出现替换为string。
index(string,substr)            返回子串的位置
length(string)                  返回字串的长度
substr(string,start,[len])      返回start开始长为len的串
match(string,regx)              返回正则表达式在string中的匹配位置
sprintf()                       返回指定格式的串
awk '{line = sprintf ( "% 15s %6.2f ", $1 , $3 ); print line}' filename
sin cos exp int log rand atan2 sqrt srand等
求子串经常用来格式化具有固定长但没有分隔符的域。而gsub通常用来替换某些无用的字符,使用替换后字符串更有意义。
自定义函数:
function name ( parameter, parameter, parameter, ... )
{
statements
return expression
}

常用awk用法举例:
 
1、awk '/101/' file 显示文件file中包含101的匹配行。 
awk '/101/,/105/' file   /pattern1/,/pattern2/ 显示两个匹配模式之间的行。在awk和sed下,如果模式2(pattern2)不出现,会显示匹配pattern1的所有行.
awk '$1 == 5' file 
awk '$1 == "CT"' file 注意必须带双引号 
awk '$1 * $2 >100 ' file 
awk '$2 >5 && $2<=15' file 
2、awk '{print NR,NF,$1,$NF}' file 显示文件file的当前记录号、域数和每一行的第一个和最后一个域。 
awk '/101/ {print $1,$2 + 10}' file 显示文件file的匹配行的第一、二个域加10。 
awk '/101/ {print $1$2}' file 
awk '/101/ {print $1 $2}' file 显示文件file的匹配行的第一、二个域,但显示时域中间没有分隔符。 
3、df | awk '$4>1000000 ' 通过管道符获得输入,如:显示第4个域满足条件的行。 
4、awk -F "|" '{print $1}' file 按照新的分隔符“|”进行操作。 
awk 'BEGIN { FS="[: /t|]" } 
{print $1,$2,$3}' file 通过设置输入分隔符(FS="[: /t|]")修改输入分隔符。 
注:awk 缺省域分隔符是空格或TAB
Sep="|" 
awk -F $Sep '{print $1}' file 按照环境变量Sep的值做为分隔符。 
awk -F '[ :/t|]' '{print $1}' file 按照正则表达式的值做为分隔符,这里代表空格、:、TAB、|同时做为分隔符。 
awk -F '[][]' '{print $1}' file 按照正则表达式的值做为分隔符,这里代表[、] 
5、awk -f awkfile file 通过文件awkfile的内容依次进行控制。 
cat awkfile 
/101/{print "/047 Hello! /047"} --遇到匹配行以后打印 ' Hello! './047代表单引号。 
{print $1,$2} --因为没有模式控制,打印每一行的前两个域。 
6、awk '$1 ~ /101/ {print $1}' file 显示文件中第一个域匹配101的行(记录)。 
7、awk 'BEGIN { OFS="%"} 
{print $1,$2}' file 通过设置输出分隔符(OFS="%")修改输出格式。 
8、awk 'BEGIN { max=100 ;print "max=" max}   BEGIN 表示在处理任意行之前进行的操作。 
{max=($1 >max ?$1:max); print $1,"Now max is "max}' file 取得文件第一个域的最大值。 
(表达式1?表达式2:表达式3 相当于: 
if (表达式1) 
表达式2 
else 
表达式3 
awk '{print ($1>4 ? "high "$1: "low "$1)}' file 
9、awk '$1 * $2 >100 {print $1}' file 显示文件中第一个域匹配101的行(记录)。 
10、awk '{$1 == 'Chi' {$3 = 'China'; print}' file 找到匹配行后先将第3个域替换后再显示该行(记录)。 
awk '{$7 %= 3; print $7}' file 将第7域被3除,并将余数赋给第7域再打印。 
11、awk '/tom/ {wage=$2+$3; printf wage}' file 找到匹配行后为变量wage赋值并打印该变量。 
12、awk '/tom/ {count++;} 
END {print "tom was found "count" times"}' file END表示在所有输入行处理完后进行处理。 
13、awk 'gsub(//$/,"");gsub(/,/,""); cost+=$4; 
END {print "The total is $" cost>"filename"}' file gsub函数用空串替换$和,再将结果输出到filename中。 
1 2 3 $1,200.00 
1 2 3 $2,300.00 
1 2 3 $4,000.00