awk 基本经常使用命令

一、AWK倾向于一行一行的数据进行处理
主要三个参数:FS、NR、NF
1>FS:定义分隔符的,没有的时候默认是空格符    格式:{FS=“:”}
    也能够多域分割
    awk  -F"[: +]" '{print $1,$2}'   ceshi
    awk  -F":| |+"  '{print $1,$2}'   ceshi
上述两种状况是同样的
2>NR:处理的是哪一行   好比:NR==1{printf 。。。。。。。} 第一行应该怎么输出
3>NF:每一行拥有的字段总数($0)数组

cat /etc/passwd |  awk '{FS=":"} $3 < 10 {print $1 "\t " $3}'  定义分隔符和条件而后输出(默认第一行仍是空格符)
cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}'  加上BEGIN能够搞定
cat pay.txt | awk 'NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total" }
NR>=2{total = $2 + $3 + $4
printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}'     *****AWK中定义变量在输出时不须要加$ui

grep --color DELETE V2.txt  |awk '{if ($2=="FROM") print $3; else print $4}'spa

AWK常与printf连用,因此对printf的语法也得熟悉
printf
%d    有符号十进制整数
%f    浮点数、十进制记数法
 %s    字符串命令行


ls -ld  /data/ww/edi/renbao |awk '{print $NF}'      直接打印出renbao    跟 $9同样字符串

awk  -F":" '{if ($3>500) print $1}'   /etc/passwd    先判断条件筛选在分割,集成了grep的功能input

当有这种状况出现时得加扩展符号,好比
aaa-bbb:::cccc     dddd
awk -F"[: ]+"  '{print $2,$3}'   上述文件
打印出cccc  dddd    就是直接以多个:或者多个空格为分隔符
it

awk  -F":"  '$3>500  {print $1}'  /etc/passwd    
awk -F":" '$1 ~ /^l/ {print $1}' /etc/passwd       匹配第一个域已c打头的行,而后打印第一个域
awk -F":" '$1 !~ /^l/ {print $1}' /etc/passwd      不是以那个打头的
awk  -F":"  BEGIN '{print "zhanghao,uid"} $3>500 {print $0}'   /etc/passwd        先打印BEGIN的输出,而后读入内容$0 表明全部
awk -F":" 'BEGIN {print "zhanghao,gid"} $3 >500 {print $1,$3} END {print "ceshi,ceshi"}' /etc/passwd      先打印BEGIN,在读完全部输出,最后打印END的内容io

awk  -F"分隔符"  'BEGIN {print "读取文件以前的初始打印值"} 模式匹配动做  {print action/执行动做}  END {print "执行完成以后最后的打印动做"}'   +filename
自带变量FILENAME  输入文件名
$0    匹配行的全部输出(按行读取)
$NF  结尾的域
$      分隔符对应的域test

自定义变量,统计目录文件总字节
ls -l |awk 'BEGIN {size=0} {size+=$5} END {print size}'
BEGIN后面接的第一个是首次读入的,余下的是没读取一个都会读入一次,END后面跟的是只有在全部输入完成以后才读入
ls -l |awk '{size=0} {size+=$5} END {print size}'  好比这个就是最后一个文件的大小,由于每次读入的时候,size清0了awk

第一次BEGIN值0,无打印
第二次读入0,打印0
第三次读入8,打印8
第四次读入210,打印218
第五次读入1995,打印2213
最后结尾在打印一遍最终的值

awk '{print NR}' filename; //打印行号
awk ‘{print $0}' filename;  //打印整行
awk '$0~/^$/ {print NR}' file   //打印整行,而后作匹配,知足匹配的就打印出行号,
awk '$0="SET "NR" "$0' 1.txt  //整行先替换成set,在打印行号,而后在输出这行内容

awk 'NF{a++;print a,$0;next}1' 1.txt  //首先匹配本行是否为空,若是为空执行默认的1打印空行,若是没有的话就不输出,非空就打印匹配规则

awk 'NR==FNR{a[FNR]=$1;b[FNR]=$2;next}NR>FNR{print a[FRN],b[FNR],$2,$3}' 2.txt 1.txt
###正向读取,先读取2.txt,a,b是随意取的别名,读取第一个文件,知足第一个条件,第一个和第二个赋值给a、b变量中的数据,当读取第二个文件时,知足第二个条件(知足读入总记录大于当前文件记录),跳过第一个动做,直接执行print(读入第二个文件时确定是大于(NR>FNR),执行后面的模块);若是第一个文件想要输出多个,直接在第一个模块加变量便可

一、当awk读取的文件只有两个的时候,比较经常使用的有两种方法
一种是awk 'NR==FNR{...}NR>FNR{...}'  file1 file2   或awk 'NR==FNR{...}NR!=FNR{...}' file1 file2
另外一种是 awk 'NR==FNR{...;next}{...}' file1 file2
了解了FNR和NR这两个awk内置变量的意义就很容易知道这两种方法是如何运做的

QUOTE:
FNR         The input record number in the current input file.       #已读入当前文件的记录数
NR          The total number of input records seen so far.            #已读入的总记录数
       next                  Stop processing the current input record.  The next input record  is
                             read  and  processing  starts over with the first pattern in the AWK
                             program.  If the end of the input data is reached, the END block(s),
                             if any, are executed.

对于awk 'NR==FNR{...}NR>FNR{...}'  file1 file2
读入file1的时候,已读入file1的记录数FNR必定等于awk已读入的总记录数NR,由于file1是awk读入的首个文件,故读入file1时执行前一个命令块{...}
读入file2的时候,已读入的总记录数NR必定>读入file2的记录数FNR,故读入file2时执行后一个命令块{...}

对于awk 'NR==FNR{...;next}{...}' file1 file2
读入file1时,知足NR==FNR,先执行前一个命令块,但由于其中有next命令,故后一个命令块{...}是不会执行的
读入file2时,不知足NR==FNR,前一个命令块{..}不会执行,只执行后一个命令块{...}

二、当awk处理的文件超过两个时,显然上面那种方法就不适用了。由于读第3个文件或以上时,也知足NR>FNR (NR!=FNR),显然没法区分开来。
因此就要用到更通用的方法了:
a、ARGIND 当前被处理参数标志: awk 'ARGIND==1{...}ARGIND==2{...}ARGIND==3{...}... ' file1 file2 file3 ...
b、ARGV 命令行参数数组:   awk 'FILENAME==ARGV[1]{...}FILENAME==ARGV[2]{...}FILENAME==ARGV[3]{...}...' file1 file2 file3 ...    
c、把文件名直接加入判断: awk 'FILENAME=="file1"{...}FILENAME=="file2"{...}FILENAME=="file3"{...}...' file1 file2 file3 ...           #没有前两种通用

awk 'ARGIND==1{A=$0;next}ARGIND==2{B=$2;c=$3;d=$4;next}ARGIND==3{print A,B,c,d,$2,$3,$4}' 1.txt 2.txt 3.txt

###等于1,先读第一个,整行赋值,等于2读取第二个,对应的分段域复制给不一样的变量,读取第三个直接打印,把前面存储的变量以及最后读取的文件须要的域直接打印便可

ovs-vsctl show |awk 'NR==1{B=$0}NF{a=$0}END{print a,B}'

 

awk if循环运用    
awk -F":" 'BEGIN{count=0;print "[start] privileges count is",count}{if($3==0){print $0}else if($3>1000){print $1,"test user";count+=2*$3}  else {print $1,$3;count+=$3}}END{print "[end] privileges count is",count}' /etc/passwd

awk 数组引用,按照顺序读取
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd

匹配$1出现的次数,key就是$1,value就是出现的次数,这种方式是无序的
awk '{array[$1]++}{for (i in array) print i,array[i]}' file

FILENAME:文件名;NR:第多少行;NF:最后一列是第多少列,加上$就是最后一列的输出
awk  -F ':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd


awk也支持常规的正常匹配,经过正则匹配来帅选须要的行在进行action

相关文章
相关标签/搜索