添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
爱跑步的钥匙  ·  MybatisPlus学习笔记 | ...·  3 周前    · 
大鼻子的手术刀  ·  ERROR! SSH Error: ...·  3 周前    · 
坏坏的红金鱼  ·  TestNG Tutorials 50: ...·  1 周前    · 
英勇无比的莴苣  ·  Better error message ...·  1 周前    · 
玩篮球的茴香  ·  [CMake教程] ...·  6 天前    · 
耍酷的茶叶  ·  Solved: HubSpot ...·  3 月前    · 
高大的脸盆  ·  Failure to install ...·  4 月前    · 

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

循环打印上述文本

for 循环的固定格式 i=1设置i的初始变量 i<=NF i变量小于等于 NF变量的值(每行的字段数) i++ 表示i递增+1,

cat sshd.txt |awk '{for(i=1;i<=NF;i++){print $i}}'
AWKPATH=.:/usr/share/awk
OLDPWD=/home/web97
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
LANG=zh_CN.GB2312
。。。。。。

说明:ENVIRON 是awk常量,是子典型数组。

sys 0m0.000s time (total=0;for i in $(seq 10000);do total=$(($total+i));done;echo $total;) 50005000 real 0m0.141s user 0m0.125s sys 0m0.008s

实现相同功能,可以看到awk实现的性能是shell的50倍!

awk的内建函数

14.8.1. 字符串函数
sub 函数匹配记录中最大、最靠左边的子字符串的正则表达式,并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的时候。格式如下:

        sub (regular expression, substitution string):
        sub (regular expression, substitution string, target string)
        $ awk '{ sub(/test/, "mytest"); print }' testfile
        $ awk '{ sub(/test/, "mytest"); $1}; print }' testfile

第一个例子在整个记录中匹配,替换只发生在第一次匹配发生的时候。如要在整个文件中进行匹配需要用到gsub

第二个例子在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候。

gsub 函数作用如sub,但它在整个文档中进行匹配。格式如下:

        gsub (regular expression, substitution string)
        gsub (regular expression, substitution string, target string)
        $ awk '{ gsub(/test/, "mytest"); print }' testfile
        $ awk '{ gsub(/test/, "mytest" , $1) }; print }' testfile

第一个例子在整个文档中匹配test,匹配的都被替换成mytest。

第二个例子在整个文档的第一个域中匹配,所有匹配的都被替换成mytest。

index 函数返回子字符串第一次被匹配的位置,偏移量从位置1开始。格式如下:

      index(string, substring)
        $ awk '{ print index("mytest", "test") }' testfile

实例返回test在mytest的位置,结果应该是3。

length 函数返回记录的字符数。格式如下:

        length( string )
        length
        $ awk '{ print length( "test" ) }' 
        $ awk '{ print length }' testfile

第一个实例返回test字符串的长度。

第二个实例返回testfile文件中第条记录的字符数。

substr 函数返回从位置1开始的子字符串,如果指定长度超过实际长度,就返回整个字符串。格式如下:

        substr( string, starting position )
        substr( string, starting position, length of string )
        $ awk '{ print substr( "hello world", 7,11 ) }' 

上例截取了world子字符串。

match 函数返回在字符串中正则表达式位置的索引,如果找不到指定的正则表达式则返回0。match函数会设置内建变量RSTART为字符串中子字符串的开始位置,RLENGTH为到子字符串末尾的字符个数。substr可利于这些变量来截取字符串。函数格式如下:

        match( string, regular expression )
        $ awk '{start=match("this is a test",/[a-z]+$/); print start}'
        $ awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'

第一个实例打印以连续小写字符结尾的开始位置,这里是11。

第二个实例还打印RSTART和RLENGTH变量,这里是11(start),11(RSTART),4(RLENGTH)。

toupper 和tolower 函数可用于字符串大小间的转换,该功能只在gawk中有效。格式如下:

        toupper( string )
        tolower( string )
        $ awk '{ print toupper("test"), tolower("TEST") }'

split 函数可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前FS值进行分割。格式如下:

        split( string, array, field separator )
        split( string, array )
        $ awk '{ split( "20:18:00", time, ":" ); print time[2] }'

上例把时间按冒号分割到time数组内,并显示第二个数组元素18。

        $ awk '{ now=strftime( "%D", systime() ); print now }'
        $ awk '{ now=strftime("%m/%d/%y"); print now }'

Table 3. 日期和时间格式说明符

$ 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开头的记录为止,或到文件末尾。

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

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

cp /etc/passwd 111.log
修改其中,增加:分隔符,把某些行的用户名,密码改为*。修改后的文件内容如下:

$$$:x:1:1:bin:/bin:/sbin/nologin
222:root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
halt:*:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
viid:x:1000:1000::/home/viid:/bin/bash

再执行上面的awk语句

cat 111.log  | awk -F: 'NF != 7{printf("line %d,does not have 7 fields:%s\n",NR,$0)} $1 !~ /[A-Za-z0-9]/{printf("line %d,non alpha and numeric user id:%d: %s\n",NR,$1,$0)}
$2 == "*" {printf("line %d, no password: %s\n",NR,$0)}'
line 1,non alpha and numeric user id:0: $$$:x:1:1:bin:/bin:/sbin/nologin
line 2,does not have 7 fields:222:root:x:0:0:root:/root:/bin/bash
line 4, no password: halt:*:7:0:halt:/sbin:/sbin/halt

-F fs or --field-separator fs
指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。

-v var=value or --asign var=value
赋值一个用户定义变量。

-f scripfile or --file scriptfile
从脚本文件中读取awk命令。

-mf nnn and -mr nnn
对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。

-W compact or --compat, -W traditional or --traditional
在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。

-W copyleft or --copyleft, -W copyright or --copyright
打印简短的版权信息。

-W help or --help, -W usage or --usage
打印全部awk选项和每个选项的简短说明。

-W lint or --lint
打印不能向传统unix平台移植的结构的警告。

-W lint-old or --lint-old
打印关于不能向传统unix平台移植的结构的警告。

-W posix
打开兼容模式。但有以下限制,不识别:\x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符=不能代替^和^=;fflush无效。

-W re-interval or --re-inerval
允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。

-W source program-text or --source program-text
使用program-text作为源代码,可与-f命令混用。

-W version or --version
打印bug报告信息的版本

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}

字符串函数例子

  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在某条件时跳过该行,对下一行执行操作。 
Sed and awk 笔记之 awk 篇:快速了解 Awk-1
Sed and awk 笔记之 awk 篇:快速了解 Awk-2
Sed and awk 笔记之 awk 篇:快速了解 Awk-3

可以点 Sed and Awk 标签查看更多内容。