`
zhengdl126
  • 浏览: 2538673 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

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"

}

 

分享到:
评论

相关推荐

    Effective AWK Programming:Awk 编程的经典著作

    AWK是一种强大的文本分析工具,常用于数据处理、报告生成和脚本编写,在UNIX和类UNIX系统中广泛使用。本书通过深入浅出的方式,详细介绍了AWK的语法、模式匹配、函数、输入/输出等方面的知识,帮助读者提升AWK编程...

    AWK命令详解

    它不仅是一个文本模式匹配工具,更是一种完整的编程语言,能够执行复杂的文本分析和数据处理任务。 #### AWK的功能 AWK的功能远远超越了基本的文本搜索工具如grep和sed。它能够执行模式匹配、数据加载、流程控制、...

    AWK是一种优良的文本处理工具

    它可以用来读取和处理输入文件、排序数据、进行计算、生成报表,以及完成许多其他任务。由于其强大的模式匹配能力,AWK在数据检索和数据转换方面尤其有用。 在不同Unix系统中,可能包含不同版本的AWK,但通常都提供...

    awk程序设计语言

    数组在awk中是一个非常重要的数据结构,可以用于保存和处理数据集合,而不需要像传统编程语言那样进行繁琐的数组索引操作。 用户自定义函数为awk添加了编程的灵活性,允许开发者封装代码以实现复用,通过简单的接口...

    The AWK Programming Language 中文版

    AWK是一种非常实用的编程语言,它在文本处理和数据分析方面表现出色。它的特点是编写程序非常简单,即便是只有一两行的程序也能完成复杂的任务。AWK非常适合那些需要快速解决特定数据处理问题的场景。 ### AWK程序...

    awk 命令简明教程

    awk实际上拥有一种专门的语言——awk程序设计语言,它被定义为一种样式扫描和处理语言。 **AWK的功能详解** 相比于sed和grep,awk的功能更为全面。它不仅能够执行这两者的基本功能,如查找和替换文本,还能进行更...

    The AWK Programming Language

    1. 数据处理和分析:AWK语言可以快速、灵活地处理大规模的文本数据,进行数据分析和处理。 2. 报表生成:AWK语言可以生成各种格式的报表,满足不同的需求。 3. 文本处理:AWK语言可以对文本进行各种操作,如格式化、...

    AWK编程实例指南.rar_AWK ns2_awk_awk unix.shell_awk编程实例

    AWK是一种强大的文本分析工具,尤其在UNIX/Linux环境中被广泛使用。它允许用户根据指定的模式匹配对输入数据进行处理,常用于数据提取、转换和报告生成。在"AWK编程实例指南.rar"这个压缩包中,我们有两个文件:"AWK...

    GAWK: Effective AWK Programming;AWK说明书

    AWK是一种编程语言,专门用于文本处理和数据提取。GAWK是AWK语言的一个GNU版本,通常简称为awk。本书为用户提供了一种指南,帮助他们有效地使用GAWK进行编程。 描述中提到的“GAWK说明;GNU awk教程”进一步确认了...

    GAWK-Effective AWK Programming - GNU Awk编程经典

    GNU Awk,又称GAWK,是一种强大的文本处理工具,它允许用户以一种简单而有效的方式在文本文件中执行复杂的模式匹配、数据提取、数据转换和报告生成。《GAWK: Effective AWK Programming - GNU Awk编程经典》是一本...

    awk语言编程使用规则

    awk 语言是一种强大的文本分析工具,它主要用于在文件或数据流中提取和处理信息。它的基本功能是基于用户定义的规则(模式)对输入数据进行分析,并根据这些规则执行相应操作(动作)。awk 通常用于格式化文本文件、...

    awk:AWK编程语言(AWK程序设计语言,awkbook)

    通过模式匹配和动作,AWK能够对这些记录进行筛选和处理。例如,你可以使用AWK轻松地从日志文件中提取特定信息,或者根据特定条件修改文件内容。 在描述中提到的"LaTeX",是另一种文本处理系统,主要用于科学和技术...

    awk知识文档学习

    Awk是一种编程语言,用于处理文本模式和报告生成。它主要用于Linux操作系统,并广泛应用于UNIX Shell编程中。Awk按照记录和字段的方式来查看文本文件,每个记录通常对应文件的一行,而字段则是记录中的数据单元,...

    shell中的awk命令

    awk是一种很棒的语言,它适合文本处理和报表生成,其语法较为常见,借鉴了某些语言的一些精华。在linux系统日常处理工作中,发挥很重要的工作。 awk程序由一个主输入循环维持,主输入循环反复执行,直到条件被触发,...

    sed和awk简明手册

    - awk是一种基于文本处理的语言,主要用于数据分析和报告生成。 - awk的强大之处在于它可以轻松处理结构化数据,并支持复杂的条件判断和数学运算。 - awk可以被视为一种小型的编程语言,具有丰富的内置函数和灵活...

Global site tag (gtag.js) - Google Analytics