awk命令:是一种用于处理数据和生成报告的编程语言

ttp://bbs.linuxtone.org/thread-1714-1-1.html

Awk学习笔记  http://www.linux.gov.cn/shell/awk.htm

 

是一种用于处理数据和生成报告的编程语言

awk 倾向于将一行分成数个字段来处理;

 

------------------------linlin

 

awk '{print}' /etc/passwd              :打印/etc/passwd所有内容
awk -F : '{print $1}' /etc/passwd                 :以 ":" 为分隔符 ,打印/etc/passwd第一字段,也就是用户名
awk -F : '{print $1 " " $2}' /etc/passwd                 :同上功能,打出第1,第二字段。  中间加个空格输出。
awk 'BEGIN{FS=":";OFS="\t";ORS="\n"}{print $1,$2}' /etc/passwd
***  FS:字段分隔符
     OFS:输出字段分隔符
     ORS:输出记录分隔符
以上命令为以 : 为分隔符,每个字段用\t隔开,输出一行后\n (换行), 输出第1,2字段。中间用,隔开
awk '{print NR}' /etc/passwd                 :读取/etc/passwd的每一行行号  (NR至今的读取记录数)
awk 'END{print NR}' /etc/passwd                  : 加了个END,读最后一个读取记录数的数字! 输出结果:29 表示29个用户
awk '/root/' /etc/passwd                   :输出 /etc/passwd里包含  root 这个字眼的 记录!打印出来 。'/ /'里表示的是符合字符

awk '{if($1~/root/) print $0}' /etc/passwd             : 如果第一个字段里有符合root字眼的,打印当前行,$0表示当前行(当前记录)
awk '/^[Rr]oot/' /etc/passwd               :   '//'里表示匹配字符  ^表示匹配第一个字母 [Rr]表示这个字母是R或者r也可以
                                     所以上面的语句表示:第一个字母符合Root或者root就打印改记录条
awk '$2~/^..u/' /etc/passwd             : ~/表示匹配,这里表示第2个字段第3个字母为u的话,就打印出该行
awk '/(lin|root)/' /etc/passwd         :记录里有匹配 lin或者root的!就打印出来

echo ababab | awk 'gsub(/a/,"c")'           : 输出  ababab  再把输出结果交给awk处理,最后吧 a换成了c .输出为 cbcbcb
awk '{if($4!~"301|302") print $0}' filename           :要是 第4个字段, 不匹配  301或者 302!就打印出该记录  !~表示不匹配,~表示匹配

awk '$1!~/^.-/'  不匹配第2个字符是 -
cat XXX.txt |grep -v "^#"|grep -v "^$" > XXX.txt  把开头是#的!全部删掉

 

cat t.log |awk '{if($3!~/note/) print $0}'|grep "2010-11-14"|wc -l  不匹配note

cat t.log |awk '{if($3~/note/) print $0}'|grep "2010-11-14"|wc -l  匹配note

cat t.log |grep -E "2010-11-14|2010-11-15" |more

cat t.log |grep -E "2010-11-14|2010-11-15" |awk '{if($3~/test/) print $0}' |more

cat /etc/passwd |cut -d ":" -f1 |grep root

cat tmp |awk '{if($3~/paijiang/ && $1~/2010-11-14/) print $0}'|wc -l

ps aux| awk '{print $2}'
cat /proc/meminfo  | awk '/MemTotal/{print $2}' 内存大小

df -h | awk '{print $5}' |grep -v 'User%'    grep -v 是删除包含 User% 的行

 


常用的作用格式:
awk ‘样式’ 文件
awk ‘{操作}’ 文件
awk ‘
{ 样式 操作}’ 文件

 

awk是一种用于处理数据和生成报告的编程语言。
一般的使用格式是:

    awk '{pattern + action}' filenames}


pattern指在每一行中进行匹配的条件,action指针对符合条件的行进行的操作,filenames是输入的文件名。

假设data文件中有以下数据:
    1 donald 305 20050129
    2 chin 102 20040129
    3 mark 304 20040229
下面对这个文件进行操作:

    awk '{print $1, $2, $3, $4}' data


而$1,$2...则相应代表分割后的列
逗号则让列与列之间插入空格

$0表示整行


输出:
    1 donald 305 20050129
    2 chin 102 20040129
    3 mark 304 20040229

 

 

 

 

-----------------awk 转义字符
\b 退格键
\t tab键
\f 走纸换页
\ddd 八进制值
\n 新行
\c 任意其他特殊字符,例如\\为反斜线符号
\r 回车符

 

 

 

 


------------条件操作符

1 匹配 ~
awk ‘{if($1~/root/) print $0}’ /etc/passwd    #如果field1包含"root",打印该行
2.精确匹配
!=  ==

3.不匹配
!~

4.大小比较
> >= < <=

5.设置大小写
awk ‘/^[Rr]oot/’ /etc/passwd # 打印包含行首为Root或者root的行
6.任意字符 .
awk ‘$2~/^…a/’ /etc/passwd # 打印第二个字段开头第四个字母为t的行
7.或关系匹配 |
awk ‘/(root|ftp)/’ /etc/passwd #打印包含"root"或者"ftp"的行
8.AND &&    OR  ||
awk ‘{$1~/mail/ && $7==/bin/bash}’ /etc/passwd

 




内置字符串函数

    gsub(r,s,t)     在字符串t中,用字符串s替换和正则表达式r匹配的所有字符串。返回替换的个数。如果没有给出t,缺省为$0
    index(s,t)       返回s 中字符串t 的位置,不出现时为0
    length(s)     返回字符串s 的长度,当没有给出s时,返回$0的长度
    match(s,r)     返回r 在s 中出现的位置,不出现时为0。设置RSTART和RLENGTH的值
    split(s,a,r)     利用r 把s 分裂成数组a,返回元素的个数。如果没有给出r,则使用FS。数组分割和字段分割采用同样的方式
    sprintf(fmt,expr_list)       根据格式串fmt,返回经过格式编排的expr_list
    sub(r,s,t)     在字符串t中用s替换正则表达式t的首次匹配。如果成功则返回1,否则返回0。如果没有给出t,默认为$0
    substr(s,p,n)     返回字符串s中从位置p开始最大长度为n的字串。如果没有给出n,返回从p开始剩余的字符串
    tolower(s)     将串s 中的大写字母改为小写,返回新串
    toupper(s)     将串s 中的小写字母改为大写,返回新串

 

 

 

 

-----------------------awk的环境变量


变量   描述
$n   当前记录的第n个字段,字段间由FS分隔
$0   完整的输入记录。
ARGC   命令行参数的数目。
ARGIND   命令行中当前文件的位置(从0开始算)。
ARGV   包含命令行参数的数组。
CONVFMT   数字转换格式(默认值为%.6g)
ENVIRON   环境变量关联数组。
ERRNO   最后一个系统错误的描述。
FIELDWIDTHS   字段宽度列表(用空格键分隔)。
FILENAME   当前文件名。
FNR   同NR,但相对于当前文件。
FS   字段分隔符(默认是任何空格)。
IGNORECASE   如果为真,则进行忽略大小写的匹配。
NF   当前记录中的字段数。   ------------------------- 域的总数
NR   当前记录数。
OFMT   数字的输出格式(默认值是%.6g)。

RS   记录分隔符(默认是一个换行符)。 -------------awk是以行为单位,也可以在这里替换为你需要的分割单位
OFS   输出字段分隔符(默认值是一个空格)。 --------awk默认以空格为字段分割符
ORS   输出记录分隔符(默认值是一个换行符)。
RLENGTH   由match函数所匹配的字符串的长度。
RSTART   由match函数所匹配的字符串的第一个位置。
SUBSEP   数组下标分隔符(默认值是\034)。

 

 

 

 

#以'----------'替换行为记录分隔符,以‘|’替代空格为输字段分隔符

awk -v RS='----------' -v OFS='|' '$1=$1' $log  > 1.txt

 

 

 

 

 

 

----------------------------------gawk专用正则表达式元字符

一般通用的元字符集就不讲了,可参考我的Sed和Grep学习笔记。以下几个是gawk专用的,不适合unix版本的awk。

\Y

匹配一个单词开头或者末尾的空字符串。
\B

匹配单词内的空字符串。
\<

匹配一个单词的开头的空字符串,锚定开始。
\>

匹配一个单词的末尾的空字符串,锚定末尾。
\w

匹配一个字母数字组成的单词。
\W

匹配一个非字母数字组成的单词。
\‘

匹配字符串开头的一个空字符串。
\'

匹配字符串末尾的一个空字符串。

 

 

 

 

-------------------------------------------- 检索用户ID值为502的用户名。

下面的命令不好:

$ grep 502 /etc/passwd | cut -d: -f1


这条命令也不够好:

$ grep 502 /etc/passwd | awk -F":" '{print $1}'


这才是一条好的命令:

$ awk -F":" '$3==502{print $1}' /etc/passwd


正如以上示例,用一条简单的awk命令就可以完成检索任务。

 

--------------------------------------------

 

 

 

    TEXT1=`cat "f1"`

    RESULT1=`echo "$TEXT1" | awk 'BEGIN {FS=","}{print $1}'`   awk取列并赋值

 

 


  awk '/donald/ {print $4}' data       匹配当data文件中包含字符串"donald"的行,输出第4列的值:


  awk '/donald|chin/ {print $1, $2}' data      这里的"|"应该是或的作用,而不是管道,输出:
    1 donald
    2 chin

    awk '/a[rl]/ {print $1, $2}' data    兼容perl的正则表达式,匹配包含"ar"或"al"的列 ,输出:
    1 donald
    3 mark

    awk '/a[rl]/ {print $1, $2, $3+1}' data       给第三列加上1再输出:
    1 donald 306
    3 mark 305

    awk '/a[rl]/ {print $1, $2} {print $3+1}' data     匹配只对第一对花括号产生作用 ,输出:
    1 donald
    306
    103
    3 mark
    305

    awk 'FS="n" {print $1}' data   使用"n"而不是空格做为分隔符,输出:

    1
    2 chi
    3 mark 304 20040229

    awk 'FS="n" {OFS="-"} {print $1, $2}' data

把分隔符输出:

    1-donald
    2 chi- 102 20040129
    3 mark 304 20040229-

    awk 'FS="n" {OFS="-"} {print NR, $1, $2}' data

使用NR变量,num of row,即行号,输出:

    1-1-donald
    2-2 chi- 102 20040129
    3-3 mark 304 20040229-

    awk '{x=x+$3} {print NR, $3, x}' data

使用变量进行累加计算,输出:

    1 305 305
    2 102 407
    3 304 711

    awk '{x=x+$3} END {print NR, $3, x}' data

使用BEGIN和END在处理之前或之后显示结果,输出:

    3 304 711

    awk '{x=x+$3} {print NR, $3, x | "sort -nr"}' data

在awk内使用管道进行排序,输出:

    3 304 711
    2 102 407
    1 305 305

    cat command
    {x=x+$3}
    {print NR, $3, x | "sort -nr"}

    awk -f command data

将指定写在文件中,输出:

    3 304 711
    2 102 407
    1 305 305

 

 

$awk '$2 == "chin" { print $3 }' 1.txt

 



如果简单的输出不能处理您的程序中所需要的复杂信息,则可以尝试由 printf 命令获得的更加复杂的输出,其语法是

printf( format, value, value ...)


该语法类似于 C 语言中的 printf 命令,而格式的规格是相同的。通过插入一项定义如何打印数值的规格,可以定义该格式。格式规格包含一个跟有字母的 %。类似于打印命令,printf 不必包含在圆括号中,但是可以认为使用圆括号是一种良好的习惯。

下表列出 printf 命令提供的各种规格。

规格 说明
%c 打印单个 ASCII 字符
%d 打印十进制数
%e 打印数字的科学计数表示
%f 打印浮点表示
%g 打印 %e 或 %f;两种方式都更简短
%o 打印无符号的八进制数
s 打印 ASCII 字符串
%x 打印无符号的十六进制数
%% 打印百分号;不执行转换

可以在 % 与字符之间提供某些附加的格式化参数。这些参数进一步改进数值的打印方式:

参数 说明
- 将字段中的表达式向左对齐
,width 根据需要将字段补齐到指定宽度(前导零使用零将字段补齐)
.prec 小数点右面数字的最大字符串宽度或最大数量

 

====================

 

文件disk.txt:

disk        used        noused    sum      
0        209715        2097152   2306867
1        209715        2097152   2306867
2        209715        2097152   2306867
3        209715        2097152  2306867
现在我想把这个文档处理成这样
硬盘        已使用        未使用     默认大小  //英文改成中文
0        0.2G        2G         2.2G     //209715k换算成G 1M=1024k 1G=1024M 并且限制小数位为1,后面加上单位名G
1        0.2G        2G         2.2G
2        0.2G        2G         2.2G
3        0.2G        2G         2.2G

======》》
awk '{if (NR==1) {print "硬盘\t已使用\t未使用\t默认大小"} else {u=$2/1024/1024; n=$3/1024/1024; s=$4/1024/1024; p=$2/$4*100; printf("%d\t%.1fG(%.0f%)\t%.1fG\t%.1fG\n",$1,u,p,n,s)}}' disk.txt

 

============================

 

$cat file
user1  par11   par12
user2  par21   par22
user1  par31   par32
awk '{if($1=="'user1'") print $1,$2,$3}' file
这样会把结果user1  par11   par12
                  user1  par31   par32   都输出来

我想当$1匹配到第一个user1的时候,就输出结果。

=====>>>>
awk '{if($1=="'user1'") {print $1,$2,$3;exit}}' file

 

 

 

 

 

$ awk '{ print $0 }' /etc/passwd
在 Awk 中,变量 $0 表示整个当前行,因此 print 和 print $0 的作用完全相同。

 

 

 

$awk -F":" '{ print $1 $3 }' /etc/passwd
halt7
operator11
root0
shutdown6
sync5
bin1

 

 

$awk -F":" '{ print "username: " $1 "\t\tuid:" $3 }' /etc/passwd

 

 

如果第一个域大于第三个域,$1就赋值给max,否则$3就赋值给max。

$ awk '{max = {$1 > $3} ? $1: $3: print max}' test

 

将显示test文件第一列中以root开头的行。

$ awk '$1 ~/^root/' test

 

如果第一和第二个域相加大于100,则打印这些行。

$ awk '$1 + $2 < 100' test。

 

 

awk '$1 > 5 && $2 < 10' test,如果第一个域大于5,并且第二个域小于10,则打印这些行。

 

$ awk '/root/,/mysql/' test将显示root第一次出现到mysql第一次出现之间的所有行。

 

 

 

============12. 一个验证passwd文件有效性的例子

1$ cat /etc/passwd | awk -F: '\
2NF != 7{\
3printf("line %d,does not have 7 fields:%s\n",NR,$0)}\
4$1 !~ /[A-Za-z0-9]/{printf("line %d,non alpha and numeric user id:%d: %s\n,NR,$0)}\
5$2 == "*" {printf("line %d, no password: %s\n",NR,$0)}'

1   

cat把结果输出给awk,awk把域之间的分隔符设为冒号。
2   

如果域的数量(NF)不等于7,就执行下面的程序。
3   

printf打印字符串"line ?? does not have 7 fields",并显示该条记录。
4   

如果第一个域没有包含任何字母和数字,printf打印“no alpha and numeric user id" ,并显示记录数和记录。
5   

如果第二个域是一个星号,就打印字符串“no passwd”,紧跟着显示记录数和记录本身。

 

 

$ awk '/^(no|so)/' test-----打印所有以模式no或so开头的行。
*

$ awk '/^[ns]/{print $1}' test-----如果记录以n或s开头,就打印这个记录。
*

$ awk '$1 ~/[0-9][0-9]$/(print $1}' test-----如果第一个域以两个数字结束就打印这个记录。
*

$ awk '$1 == 100 || $2 < 50' test-----如果第一个或等于100或者第二个域小于50,则打印该行。
*

$ awk '$1 != 10' test-----如果第一个域不等于10就打印该行。
*

$ awk '/test/{print $1 + 10}' test-----如果记录包含正则表达式test,则第一个域加10并打印出来。
*

$ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' test-----如果第一个域大于5则打印问号后面的表达式值,否则打印冒号后面的表达式值。
*

$ awk '/^root/,/^mysql/' test----打印以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。如果找到一个新的正则表达式root开头的记 录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾。

 

 

awk '$1 ~/test/{count = $2 + $3; print count}' test,上式的作用是,awk先扫描第一个域,一旦test匹配,就把第二个域的值加上第三个域的值,并把结果赋值给变量count,最后打印出来。

 

$ awk '{if ($1 <$2) print $2 "too high"}' test。如果第一个域小于第二个域则打印。
$ awk '{if ($1 < $2) {count++; print "ok"}}' test.如果第一个域小于第二个域,则count加一,并打印ok。

 

 

$ awk '{if ($1 > 100) print $1 "bad" ; else print "ok"}' test。如果$1大于100则打印$1 bad,否则打印ok。

$ awk '{if ($1 > 100){ count++; print $1} else {count--; print $2}' test。如果$1大于100,则count加一,并打印$1,否则count减一,并打印$1。

 

 

====================awk有三种循环:while循环;for循环;special for循环。
*

$ awk '{ i = 1; while ( i <= NF ) { print NF,$i; i++}}' test。变量的初始值为1,若i小于可等于NF(记录中域的个数),则执行打印语句,且i增加1。直到i的值大于NF.
*

$ awk '{for (i = 1; i<NF; i++) print NF,$i}' test。作用同上。
*

breadkcontinue语句。break用于在满足条件的情况下跳出循环;continue用于在满足条件的情况下忽略后面的语句,直接返回循环的顶端。如:

{for ( x=3; x<=NF; x++)
if ($x<0){print "Bottomed out!"; break}}
{for ( x=3; x<=NF; x++)
if ($x==0){print "Get next item"; continue}}


*

next语句从输入文件中读取一行,然后从头开始执行awk脚本。如:

{if ($1 ~/test/){next}
else {print}
}


*

exit语句用于结束awk程序,但不会略过END块。退出状态为0代表成功,非零值表示出错。

 

 

 

 

--------------------

 

1 awk '/101/' file 显示文件 file 中包含 101 的匹配行。
IXDBA.NET技术社区
awk '/101/,/105/' file
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|]" )修改输入分隔符。
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

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

通过 if else if 完成条件语句

awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000&&$4<4000) exit;
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) next;
else c4+=$4; }
END {printf "c4=[%d]\n",c4}"' file

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


14
awk '{ print FILENAME,$0 }' file1 file2 file3>fileall
file1 file2 file3 的文件内容全部写到 fileall 中,格式为打印文件并前置文件名。
15
awk ' $1!=previous { close(previous); previous=$1 }
{print substr($0,index($0," ") +1)>$1}' fileall


把合并后的文件重新分拆为 3 个文件。并与原文件一致。
16
awk 'BEGIN {"date"|getline d; print d}'
通过管道把 date 的执行结果送给 getline ,并赋给变量 d ,然后打印。
17
awk 'BEGIN {system("echo \"Input your name:\\c\""); getline d;print "\nYour name is",d,"\b!\n"}'
通过 getline 命令交互输入 name ,并显示出来。
awk 'BEGIN {FS=":";while(getline< "/etc/passwd" >0) { if($1~"050[0-9]_") print $1}}'
打印 /etc/passwd 文件中用户名包含 050x_ 的用户名。

18
awk '{ i=1;while(i
awk '{ for(i=1;i
type file|awk -F "/" '
{ for(i=1;i
{ if(i==NF-1) { printf "%s",$i }
else { printf "%s/",$i } })'

显示一个文件的全路径。


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}
}
}
}'
19
awk 中调用系统变量必须用单引号,如果是双引号,则表示字符串
Flag=abcd
awk '{print '$Flag'}'
结果为 abcd
awk '{print "$Flag"}'
结果为 $Flag

 

 

 

 

 

---------------------------------awk应用小结(所有命令行均经调试)

 

 

1.调用awk:

第一种方式:命令行方式
awk [-F field-separator] 'commands' input-file(s)
[-F域分隔符]是可选的,因为awk使用空格作为缺省的域分隔符,因此如果要浏览域间有空格的文本,不必指定这个选项,如果要浏览诸如passwd文件,此文件各域以冒号作为分隔符,则必须指明-F选项,如:
awk -F: 'commands' input-file

第二种方式是将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它。

第三种方式是将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-scrīpt-file input-files(s)
-f选项指明在文件awk_scrīpt_file中的awk脚本,input_file(s)是使用awk进行浏览的文件名。


模式和动作

任何awk语句都由模式和动作组成。在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式 部分,动作将时刻保持执行状态。模式可以是任何条件语句或复合语句或正则表达式。模式包括两个特殊字段 BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文本开始执行。END语 句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志。

域和记录
使用$1,$3表示参照第1和第3域,注意这里用逗号做域分隔。如果希望打印一个有5个域的记录的所有域,可使用$0,意即所有域。
为打印一个域或所有域,使用print命令。这是一个awk动作

模式和动作
模式 :两个特殊断 BEGIN和END
动作 :实际动作大多在{}内指明


输出
1.抽取域
awk -F: '{print $1}' /etc/passwd

2.保存输出
awk -F: '{print $1}' /etc/passwd | tee user 使用tee命令,在输出文件的同时,输出到屏幕

使用标准输出
awk -F: '{print $1}' /etc/passwd >user3

4.打印所有记录
awk -F: '{print $0}' /etc/passwd

5.打印单独记录
awk -F: '{print $1,$4}' /etc/passwd

6.打印报告头
awk -F: 'BEGIN {print "NAME\n"} {print $1}' /etc/passwd

7.打印结尾
awk -F: '{print $1} END {print "this is all users"}' /etc/passwd


条件操作符
1.匹配
awk -F: '{if($1~/root/) print }' /etc/passwd      //{if($1~/root/) print}表示如果field1包含root,打印它

2.精确匹配
使用等号 ==
awk -F: '{if($3=="0") print }' /etc/passwd  

3.不匹配
!~
awk -F: '{if($1!~/linuxtone/) print }' /etc/passwd

!=
精确不匹配
awk -F: '{if($1!="linuxtone") print }' /etc/passwd

4.小于
<
5.小于等于
<=
6.大于
>
.........
7.设置大小写
awk '/[Rr]oot/' /etc/passwd

8.任意字符
awk -F: '{if($1~/^...t/) print}' /etc/passwd      //^...t表示第四个字幕是t

9.或关系匹配
awk -F: '{if ($1~/(squid|nagios)/) print}' /etc/passwd

10.行首
awk '/^root/' /etc/passwd       // ^root(行首包含root)

11.AND &&
awk -F: '{if($1=="root" && $3=="0") print}' /etc/passwd

12.OR ||


打印有多少行记录
awk 'END {print NR}' /etc/passwd

设置输入域到变量名
awk -F: '{name=$1; path=$7; if(name~/root/) print name  "\tpath is:" path}' /etc/passwd

域值比较操作
awk '{if($6<$7) print $0}' input-file

修改文本域只显示修改改记录
awk -F: '{if($1=="nagios") {$1="nagios server" ; print }}' /etc/passwd

文件长度相加
ls -l|awk '/^[^d]/ {print $9"\t" $5} {tot+=$5} END {print "total kb:"tot}'

内置的字符窜函数
gsub(r,s)                                                      在整个$0中用s替代r
gsub(r,s,t)                                                    在整个t中用s替代r
index(s,t)                                                     返回s中字符串t的第一位置
length(s)                                                      返回s长度
match(s,r)                                                     测试s中是否包含匹配r的字符串
split(s,a,fs)                                                  在fs上将s分成序列a
sub(s, )                                                       用$0中最左边也是最长的字符串替代
subtr(s,p)                                                     返回字符串s中从p开始的后缀部分
substr(s,p,n)                                                  返回字符串s中从p开始长度为n的后缀部分

1.gsub
awk 'gsub(/^root/,"netseek") {print}' /etc/passwd             将与root开头的root替换为netseek

awk 'gsub(/0/,2) {print}' /etc/fstab

awk '{print gsub(/0/,2) $0}' /etc/fstab                       

2.index
awk 'BEGIN {print index("root","o")}'  查询字符串root中o出现的第一位置

awk -F: '$1=="root" {print index($1,"o")" "$1}' /etc/passwd

awk -F: '{print index($1,"o") $1}' /etc/passwd

3.length
awk -F: '{print length($1)'} /etc/passwd

awk -F: '$1=="root" {print length($1)}' /etc/passwd

4.match (在ANCD中查找C的位置)
awk 'BEGIN {print match("ANCD",/C/)}'

5.split
返回字符串数组元素个数
awk 'BEGIN {print split("123#456#789", myarray, "#")}'

6.sub   只能替换指定域的第一个0
awk 'sub(/0/,2) {print }' /etc/fstab

7.substr
按照起始位置及长度返回字符串的一部分
awk 'BEGIN {print substr("www.linuxtone.org",5,9)}'  //第5个字符开始,取9个字符。

awk 'BEGIN {print substr("www.linuxtone.org",5)}'  //第5个位置开始,取后面的所有.

字符串屏蔽序列
\b                  退格键
\f                  走纸换页
\n                  新行
\r                  回车
\t                  tab
\c                  任意其他特殊字符
\ddd                八进制

很简单的例子
awk -F: '{print $1,"\b"$2,"\t"$3}' /etc/passwd 输出函数printf(注意是printf不是print,两者效果不同的)
printf函数拥有几种不同的格式化输出功能

printf修饰符
-                               左对齐
Width                        域的步长0表示0步长
.prec                          最大字符串长度,或小数点右边的位数


awk printf格式
%c                              ASCII字符
%d                              整数
%e                              浮点数,科学计数法
%f                               浮点数
%g                              awk决定使用哪种浮点数转换,e或者f
%o                              八进制数
%s                              字符串
%x                              十六进制数

1.字符串转换
echo "65" | awk '{printf"%c\n",$0}'

awk 'BEGIN {printf "%c\n",65}'

awk 'BEGIN {printf "%f\n",999}'

2.格式化输出
awk -F: '{printf "%-15s %s\n",$1,$3}' /etc/passwd

awk -F: 'BEGIN {printf"USER\t\tUID\n"} {printf "%-15s %s\n",$1,$3}' /etc/passwd

3.向一行awk命令传值
who | awk '{if ($1 == user) print $1 " you are connected to:" $2}' user=$LOGNAME

4.awk脚本文件 (在文件名字后面加后缀.awk方便区分)
#!/bin/awk -f
BEGIN{
    FS=":"
        print "User\t\tUID"
        print"____________________________"
}

{printf "%-15s %s\n",$1,$3}

END{
       print "END"

}

 

你可能感兴趣的:(编程,mysql,正则表达式,F#,D语言)