awk 简易手册

(0 comments)

语法格式

awk 'pattern' file
awk '{action}' file
awk 'pattern {acction}' file

内建变量

符号 说明 默认值
ARGC 命令行变量个数
ARGV 命令行变量数组
FILENAME 当前输入文件名
FNR 当前文件中的记录号
FS 输入域分隔符 空格
RS 输入记录分割符 回车
NF 当前记录里域个数
NR 到目前为止记录数(行号)
OFS 输出域分隔符 空格
ORS 输出记录分隔符 回车
$0 整条记录
$n 记录的第N个区域

全文匹配

awk '/101/' file                    # 匹配字符串所在行
awk '/101/,/105/' file              # 匹配两个字符串之间的所有行

域匹配

awk '$3 == 5245' file               # 匹配数字
awk '$4 > 1000' file
awk '$1 * $2 >100' file
awk '$2 >5 && $2<=15' file
awk '$1 == "CT"' file               # 匹配字符串
awk '$2 ~ /Adm/' file               # 匹配正则表达式
awk '$2 !~ /Adm/' file 

打印输出

awk '{print NR,NF,$1}' file        # 打印文件的当前记录号、域数和每一行的第一个域
awk '{print $NF}' file             # 打印文件的每一行的最后一个域
awk '{print "Month: " $2 "\nYear: ", $6}' file      # 打印格式化内容
awk '/101/ {print $1,$2 + 10}' file     # 打印匹配条件的每一行的第一、二个域加10
awk '/101/ {print $1 $2}' file          # 打印时每个域中间没有分隔符

值域处理

awk '{$1 == 'Chi' {$3 = 'China'; print}' file   # 找到匹配行后先将第3个域替换后再显示该行(记录)。
awk '{$7 %= 3; print $7}'  file               #将第7域被3除,并将余数赋给第7域再打印。

把file1、file2、file3的文件内容全部写到fileall中,格式为打印文件并前置文件名。

awk '{ print FILENAME,$0 }' file1 file2 file3>fileall 

把合并后的文件重新分拆为3个文件。并与原文件一致。

awk ' $1!=previous { close(previous); previous=$1 }   
{print substr($0,index($0," ") +1)>$1}' fileall 

输入域分隔符

默认输入域分隔符是空格,可以通过-F,修改默认的输入域分隔符。输出分隔符是',' 就是OFS的值。

awk -F "|" '{print $1}' file         # 按照新的分隔符"|"进行操作
awk -F: '/101/{print $1, $2}' file   # 非特殊字符,可以不加引号
awk 'BEGIN { FS="[: \t|]"}           # 通过FS修改输入分隔符
{print $1,$2}' file                                  
awk -F $Sep '{print $1}' file        # 按照系统环境变量的值做为分隔符
awk -F '[ :\t|]' '{print $1}' file   # 按照正则表达式的值做为分隔符

输出域分隔符

通过设置输出分隔符(OFS)修改输出输出符号。

awk 'BEGIN { OFS="%"} {print $1,$2}'

格式化输出

printf 函数支持复杂的格式化输出,参数 %-15s 表示左对齐,%8d 表示右对齐,15s 表示变量占15个位置。

awk '{printf "The name is: %-15s ID is %8d\n", $1, $3}'

定义变量

给变量赋值,然后打印该变量。

awk '/tom/ {wage=$2+$3; printf wage}' file
awk '/tom/ {count++;}
END {print "tom was found "count" times"}' file

通过管道把date的执行结果送给getline,并赋给变量d,然后打印。

awk 'BEGIN {"date"|getline d; print d}'        

BEGIN 表示在处理任意行之前进行的操作。END表示在所有输入行处理完后进行处理。

调用系统变量

调用系统变量必须用单引号,如果是双引号,则表示字符串。

Flag=abcd
awk '{print '$Flag'}'           # 结果为abcd
awk '{print  "$Flag"}'          # 结果为$Flag 

条件判断

建立文件file,内容如下:

1 2 3 $1,200.00
1 2 3 $2,300.00
1 2 3 $4,000.00

gsub函数用空串替换$和,再将结果输出到filename中。

awk 'gsub(/\$/,"");gsub(/,/,""); cost+=$4;
END {print "The total is $" cost>"filename"}' file 

通过if和else if完成条件语句

awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>1000&&$4<2000) c1+=$4;
else if ($4>2000&&$4<3000) c2+=$4;
else if ($4>3000&&$4<4000) c3+=$4;
else c4+=$4; }
END {printf  "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}' file

通过exit在某条件时退出,但是仍执行END操作。

awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000&&$4<5000) exit;
else c4+=$4; }
END {printf  "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}' file

通过next在某条件时跳过该行,对下一行执行操作。

awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000) next;
else c4+=$4; }
END {printf  "c4=[%d]\n",c4}"' file

表达式1?表达式2:表达式3 相当于:

if (表达式1)
    表达式2
else
    表达式3

例如:

awk '{print ($1>4 ? "high "$1: "low "$1)}' file

取得文件第一个域的最大值

awk 'BEGIN { max=100 ;print "max=" max}             
{max=($1 >max ?$1:max); print $1,"Now max is "max}' file 

循环

For

通过For语句实现循环。

awk '{for(i=1;i<=NF;i++) {print NR,$i}}' file

下面通过For与IF语句,打印一个简单的日历表。

awk  'BEGIN {
for(j=1;j<=12;j++)
{ flag=0;
  printf "\n%d月份\n",j;
        for(i=1;i<=31;i++)
        {
        if (j==2&&i>28) flag=1;
        if ((j==4||j==6||j==9||j==11)&&i>30) flag=1;
        if (flag==0) {printf "%02d%02d ",j,i}
        }
}
}'

While

通过while语句实现循环。

awk '{ i=1;while(i<=NF) {print NR,$i;i++}}' file

显示一个文件的全路径。

echo "/usr/bin/bash" |awk -F "/" '
{ for(i=1;i<NF;i++)
{ if(i==NF-1) { printf "%s",$i }
else { printf "%s/",$i } }}'              

交互模式

通过getline命令交互输入name,并显示出来。

awk 'BEGIN {system("echo -e \"Input your name: \\c\""); 
getline d;print "\nYour name is",d,"\b!\n"}'

打印/etc/passwd文件中用户名包含07x_的用户名。

awk 'BEGIN {FS=":"; while(getline< "/etc/passwd" >0) 
{ if($1~"07[0-9]_") print $1}}'
Currently unrated

Comments

There are currently no comments

New Comment

required

required (not published)

optional

required