awk 基本常用命令

1、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中定义变量在输出时不需要加$

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

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的功能

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

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的内容

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

自定义变量,统计目录文件总字节
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了

第一次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),执行后面的模块);如果第一个文件想要输出多个,直接在第一个模块加变量即可

1、当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,前一个命令块{..}不会执行,只执行后一个命令块{...}

2、当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

转载于:https://my.oschina.net/u/2343310/blog/877589

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值