grep 文本过滤工具

 sed stream editor 流文本处理工具

  awk 格式化的报告生成工具


awk的输出

#awk [options] 'script' file1, file2, ....

#awk [options] 'pattern ( action )' file1, file2, ....

一,print

格式

      print item1, itme2, ....

要点

1, 各项目之间用逗号隔开,而输入时则以空白字符分割

2, 输出的item可以为字符串或数值,当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,而后在输出

3, print命令后面的itme可以省略, 此时其功能相当于print $0,因此,如果想输入空白行, 则需要使用print "";


列子;

#awk 'BEGIN {print "line one\nline two\nline three"}'

awk -F: '{ print $1, $2 }' /etc/passwd


内置变量

ORS output record separator

OPS output filed separator

FS:filed separator 默认是空白字符

RS:RECORD separator 默认是换行符

NR: The number of input records, awk 命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数

NF:number of filed, 当前记录的field个数

FNR:与nr不同的是,FNR用于记录正在处理得行是当前这一文件中被总共被处理的行数

ARGV:数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt 这个命令中,ARGV[0]保存awk,ARGV[1] a.txt

ARGC:awk 命令参数的个数


二,printf

printf命令的使用格式;

printf format, item1, item2, ...


要点:

1,其余print命令的最大的不同在于,printf需要先制定format

2,format用于制定后面每个itme的输入格式

3,printf语句不会自动打印换行符:\n


format格式的指示符都以%开头,后跟一个字符:如下

%c:显示字符的ancii码

%d,%i:十进制整数

%e,%E:科学计数法显示数值

%f:显示浮点数

%g,%G:以科学技术法的格式或浮点数的格式显示数值

%s:显示字符串

%u:无符号整数

%%:显示%自身


修饰符:

N:显示宽度

-:左对齐

+:显示数值符号


例子

#awk -F: '{pintf "%-15s %i\n",$1,$3}' /etc/passwd


三,输入重定向

print items > output-file

print iems >> output-file

print items |commant


特使文件描述符

/dev/stdin:标准输入

/dev/stdout:标准输出

/dev/stderr:错误输入

/dev/fd/N:某特定文件描述符,如,/dev/stdin就相当于/dev/fd/0;


例子

#awk -F: '{printf "%-15s %i\n",$1,$3 > "/dev/stderr" }' /etc/passwd



awk的操作符

一,算术操作符;


-x:负值

+x:转换为数值

x^y:平方

x**y:次方

x/y:除法

x+y

x-y

x%y:去摸



二,字符操作符

只有一个,不用写出来


例子

#awk 'BEGIN{prin "hello, " "word!"}'


三,赋值操作符

=

+=

-=

/=

++

--


需要注意的是,如果莫模式为=号,此时使用/=/可能有语法错误,应以/[=]/代替;


四,布尔值

awk中,任何非0值或非空字符串都为真,反之就为假


五,比较操作符

x < y

x <= y

x > y

x >= y

x == y 等

x != y

x ~ y 去模,

x !~ y

例子

#awk -F: '$1 ~ /^root/ {print $3,$NF}' /etc/passwd


六,表达式间的逻辑关系

&& 和

||或


七,条件表达式

select?if-true-exp:if-false-exp


八,函数调用

function_name (para1,para2)



awk的模式


awk 'program' input-file1 input file2 ...

其中的program

pattern ( action )

pattern ( action )

...


常见的模式类型

1,Regexp:正则表达式,格式为/regular expression

2,expression:表达式,其值非0或非空字符时满足条件,如$1 ~ /foo/ 或$ == "sxz",用运算符~(匹配)和!~(不匹配)

3,Ranges:制定的匹配范围,格式为part1,part2

4,BEGIN/END:特殊模式,尽在awk命令执行前运行一次或结束前运行一次

5,Empty(空模式):匹配任意输出行;


常见的action有:

1,expressions

2,control statements

3,compound statements

4,input statements

5,output statements


/正则表达式/:使用统配符的扩展集。


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


模式匹配表达式


模式,指定一个行的范围,该语法不能包括BEGIN和END模式


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

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




控制语句

1,if-else

语法:if (condition) then-body [ else-body ]

例子:

awk -F: '{if ($1=="root") print $1, "admin"; else print $1, "common user"}' /etc/passwd

awk -F: '{if ($1=="root") printf "%-15S: %s\n","admin";else printf "%-15s: %s\n",$1,"common user"}' /etc/passwd

awk -F: -v sum=0  '{if ($3>500) sum++}END{print sum}' /etc/passwd


2,while

语法:while (condition){statement1;statement2;...}

#awk -F: '{i=1;while (i<3) {print $i;i++}}' /etc/passwd


3,do-while

语法:do {stement1,stement2,....} while (condition)

#awk -F: '{i=1;do {print $i;i++}while(i<3)}' /etc/passwd


4,for

语法: for (variable assignment;condition;iteration process) {statement1,statement2,....}

#awk -F: '{for(i=1;i<3;i++) print $i}' /etc/passwd


for循环还可以用来编历数组元素

语法: for (i in aray) {stetement1,stetement2,...}



5,case

语法:switch (expression) {case value or /REGEXP/; statement,statement,... default;statement1,...


6,break和continue

常用语循环或case语句中


7,next

提前结束本行文本处理,并接着处理下一行




awk中使用数组

array[index-expression]


index-expression可以使用任意字符串;需要注意的是,如果某元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。


要遍历数组中的每一个元素,需要使用如下的特殊结构;

for {var in array} ( statement,...)

其中,var用于引用数组下标;


例子:

#awk 'BEGIN{a["m"]="hello";a["n"]="word";for(B in a) print a[B]}'


#netstat -ant |awk '$1~/tcp/ {S[$NF]++}END{for (A in S) printf  "%11s:%s\n",A,S[A]}'


#awk -F: '$NF!~/^$/{SHELL[$NF]++}END{for (A in SHELL) print A ,SHELL[A]}' /etc/passwd


awk '(counts[$1]++); END{for(url in counts) print counts[url], url}' /var/log/httptd/access_log



[root@182 1]# awk 'BEGIN{FS=OFS="|"}{a[$2]+=$1;b[$2]=b[$2]$NF"/"}END{for(i in a)print  a[i],i,b[i]}' file

15335|Block "5874: HTTP: .dat File Request"|192.168.11.254/192.168.11.253/192.168.11.250/192.168.11.251/192.168.11.252/

[root@182 1]# cat file

3231|Block "5874: HTTP: .dat File Request"|192.168.11.254

3108|Block "5874: HTTP: .dat File Request"|192.168.11.253

3059|Block "5874: HTTP: .dat File Request"|192.168.11.250

3025|Block "5874: HTTP: .dat File Request"|192.168.11.251

2912|Block "5874: HTTP: .dat File Request"|192.168.11.252



cat aa.txt

2013-03-24 19:11 testlog1

FINE:testlog1="test_log_line1"

2013-03-24 19:12 testlog2

FINE:testlog2="test_log_line2"

2013-03-24 19:13 testlog3

ALARM:testlog3="test_log_line3"


命令

[root@station007 tmp]# sed 'N;s/\n/ /g' aa.txt |cut -d : -f 1,2 |awk 'BEGIN{printf "%-22s %-11s %-11s\n","TIME","LEVEL","INFO"}{printf "%s %-11s %-11s %-11s\n",$1,$2,$4,$3}END{printf "%s %s %s\n","there is",NR,"logs"}'

TIME                   LEVEL       INFO      

2013-03-24 19:11       FINE        testlog1  

2013-03-24 19:12       FINE        testlog2  

2013-03-24 19:13       ALARM       testlog3  

there is 3 logs



oldboy=`sed 's/[:a-z:]/ /g' sxztest.txt |awk -F '-' '{printf "%-s\n%-s\n",$1,$2}'`


N=`sed 's/[:a-z:]/ /g' sxztest.txt |awk -F '-' '{print $1}'`

M=`sed 's/[:a-z:]/ /g' sxztest.txt |awk -F '-' '{print $2}'`


#!/bin/bash

N=`sed 's/[:a-z:]/ /g' sxztest.txt |awk -F '-' '{print $1}'`

M=`sed 's/[:a-z:]/ /g' sxztest.txt |awk -F '-' '{print $2}'`

while [ $N -le $M ]

do

if [ $N -le 109 ]

then

printf stu$N,

let N++

else

echo stu$N

let N++

fi

done