Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1808944
  • 博文数量: 636
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 3950
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-06 21:58
个人简介

博客是我工作的好帮手,遇到困难就来博客找资料

文章分类

全部博文(636)

文章存档

2024年(5)

2022年(2)

2021年(4)

2020年(40)

2019年(4)

2018年(78)

2017年(213)

2016年(41)

2015年(183)

2014年(66)

我的朋友

分类: 系统运维

2015-09-08 12:30:08

echo  `seq 0 2 100`

echo  `seq 1 3 100`  

echo  `seq 2 2 100` 

打印行号  awk '{print NR":"$0}'


                     打印偶数行、奇数行

 (1)  awk '{print $0 > NR%2}'  file


 (2)  sed -n '1~2p'  file   

          sed -n '2~2p' file


 (3)   sed -n 'p;n'  file

       sed -n 'n;p'  file


 (4)  1,awk 'NR%2==1' file

       2,awk 'NR%2==0' file


 (5) 1.awk 'NR%2' file
       2.awk '!(NR%2)' file


 (6) 1.awk 'i=!i' file

       2.awk '!(i=!i)' file

解释:

awk 'var=xx'应该说等价于awk 'xx{print}{var=xx}'

awk 'i=!i'  == >  awk '!i{print}{i=!i}

line 1: !0{print}{i=!0}==> {print;i=1}

line 2: !1{print}{i=!1}==> {i=0}

line 3: !0{print}{i=!0}==> {print;i=1}

1.awk 'NR%2==1' file  / /显示奇数行
2.sed -n '1,$n;p' file   / /显示偶数行
3.sed -n '1,$p;n' file / /显示奇数行
4.奇数行:sed '2~2d' file / /显示奇数行
5.偶数行:sed '1~2d' file/ /显示偶数行



sed '1d;n;d'  status.txt
sed -n 'n;p' status.txt
sed -n '0~2p' status.txt
awk '!(NR%2)' status.txt
awk 'i++%2' status.txt
awk '!(i=i?0:1)' status.txt
awk '!(i=!i)' status.txt



[root@sgzhang /]# cat -n tt
     1  aaa
     2  bbb
     3  ccc
     4  ddd
     5  eee
     6  fff
[root@sgzhang /]# cat -n  tt |awk NR%2==0
     2  bbb
     4  ddd
     6  fff
[root@sgzhang /]# cat -n  tt |awk NR%2==1
     1  aaa
     3  ccc
     5  eee
[root@sgzhang /]# cat -n tt |sed -n 'p;n'
     1  aaa
     3  ccc
     5  eee
[root@sgzhang /]# cat -n tt |sed -n 'n;p'
     2  bbb
     4  ddd
     6  fff


$ seq 6 | awk 'NR%2'

1

3

5

$ seq 6 | awk '!(NR%2)'

2

4

6




$ seq 6 | awk '++i%2'

1

3

5

$ seq 6 | awk 'i++%2'

2

4

6



$ seq 6 | awk 'i=!i'     

1

3

5

$ seq 6 | awk -vi=1 'i=!i'

2

4

6



$ seq 6 | sed -n 'N;P'

1

3

5

$ seq 6 | sed -n 'n;p'

2

4

6



一. 行距:

1. 每行间加一个空行


awk '1; { print "" }'   filname.ext             #输出当前行,在输出一个空行

awk '1 { print } { print "" }'   filname.ext

awk '{ print } { print "" }'   filname.ext

2. 1的另外一种实现方法:


awk 'BEGIN { ORS="\n\n" }; 1'   filname.ext    #预先设置每一行的分隔符号为两个换行;你可以尝试把ORS设置为其他的看看效果如何

3. 仅输出非空行,并每行间在加一个空行


awk 'NF { print $0 "\n" }'   filname.ext       #NF表示当前行的字段数,$0表示当前行,最后再加一个换行

4. 双倍行距;没行间两个空行


awk '1; { print "\n" }'   filname.ext     #默认输出后会换行的,输出\n,则会输出两个空白行

等同于:


awk '{ print; print "\n" }'   filname.ext

5. 显示当前行在所在文件中的行号


awk '{ print FNR "\t" $0 }'   filname.ext      #FNR,表示当前行在文件中的行号

6. 显示当前行在本次处理过程中的行号


awk '{ print NR "\t" $0 }'   filname.ext       #NR,表示当前行在本次处理过程中的行号

小疑问:为啥有FNR和NR的差别呢?效果不都是一样么? 如果你给如:filname1.ext filname2.ext,你就会看到差别了。原来:FNR,是每个文件中的,换了一个文件,会归零;而NR则每个文件会累加起来的


7. 使用简单样式来输出


awk '{ printf("] : %s\n", NR, $0) }'   filname.ext    #行号占用5位,不足补空格

8. 显示非空行


awk 'NF { $0=++a " :" $0 }; { print }'   filname.ext

#NF前面说了,表示当前行的行号,此处用他作为条件,如果是空行,则NF为0,跳过;否则,用动态变量a存储非空行的数目

9. 计算行数:效果类似wc -l


awk 'END { print NR }'   filname.ext    #END表示每行都处理完了后,在执行,此时NR就是最后一行的行号,也就是总的行数了。

10. 计算每一行的和


awk '{ s = 0; for (i = 1; i <= NF; i++) s = s+$i; print s }'   filname.ext

#s用作每行和的累加,从1到NF(每行总的字段数),依次累加


11. 计算文件中所有字段的和


awk '{ for (i = 1; i <= NF; i++) s = s+$i }; END { print s }'   filname.ext

#s用作总和的累加,每行都处理完成了,再输出s;注意和10对比,此处没有每行清零,所以累加了。没有设置的变量,默认为空,但是会根据上下文数值计算情况自动变为0

12. 将每个字段用其绝对值代替

awk '{ for (i = 1; i <= NF; i++) if ($i < 0) $i = -$i; print }'  filname.ext

#$i表示当前行中的字段,$0表示当前行,可以改变$i的值

13. 计算文件中总的字段和(例如计算单词数)

awk '{ total = total + NF }; END { print total }'  filname.ext

14. 计算匹配指定信息的总行数

awk '/Linux/ { n++ }; END { print n+0 }'  filname.ext

15. 找到文件中每行第一个字段中,最大的数,以及其所在的行

awk '$1 > max { max=$1; maxline=$0 }; END { print max, maxline }'  filname.ext

#用max存储最大的数,maxline存储最大数所在的行,并在最后输出

16. 显示当前行的字段数,并输出当前行

awk '{ print NF ":" $0 } '  filname.ext

17. 显示每行最后一个字段的内容

awk '{ print $NF }'  filname.ext   #NF表示当前行的字段数,例如为3,则$NF,就是$3,也就是第三个字段了

18. 显示最后一行的最后一个字段

awk '{ field = $NF }; END { print field }'  filname.ext

#每行处理没有输出,尽在最后输出,field作为每行的最后一行的暂存变量

19. 显示字段数小于4的行

awk 'NF < 4'  filname.ext   #{}以外的内容,作为条件,没有{},则默认输出当前行

20. 显示每行的最后一个字段小于4的行

awk '$NF < 4'  filname.ext   #注意和19对比


知识点:
1)数组
数组是用来存储一系列值的变量,可通过索引来访问数组的值。
Awk中数组称为关联数组,因为它的下标(索引)可以是数字也可以是字符串。
下标通常称为键,数组元素的键和值存储在Awk程序内部的一个表中,该表采用散列算法,因此数组元素是随机排序。
数组格式:


array[index]=value



1、Nginx日志分析
    日志格式:'$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"'
    日志记录:27.189.231.39 - - [09/Apr/2016:17:21:23 +0800] "GET /Public/index/images/icon_pre.png HTTP/1.1" 200 44668 "" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36" "-"

    1)统计日志中访问最多的10个IP
        思路:对第一列进行去重,并输出出现的次数
        方法1:$ awk '{a[$1]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
        方法2:$ awk '{print $1}' access.log |sort |uniq -c |sort -k1 -nr |head -n10
        说明:a[$1]++ 创建数组a,以第一列作为下标,使用运算符++作为数组元素,元素初始值为0。处理一个IP时,下标是IP,元素加1,处理第二个IP时,下标是IP,元素加1,如果这个IP已经存在,则元素再加1,也就是这个IP出现了两次,元素结果是2,以此类推。因此可以实现去重,统计出现次数。

    2)统计日志中访问大于100次的IP
        方法1:$ awk '{a[$1]++}END{for(i in a){if(a[i]>100)print i,a[i]}}' access.log
        方法2:$ awk '{a[$1]++;if(a[$1]>100){b[$1]++}}END{for(i in b){print i,a[i]}}' access.log
        说明:方法1是将结果保存a数组后,输出时判断符合要求的IP。方法2是将结果保存a数组时,并判断符合要求的IP放到b数组,最后打印b数组的IP。
    3)统计2016年4月9日一天内访问最多的10个IP
        思路:先过滤出这个时间段的日志,然后去重,统计出现次数
        方法1:$ awk '$4>="[9/Apr/2016:00:00:01" && $4<="[9/Apr/2016:23:59:59" {a[$1]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
        方法2:$ sed -n '/\[9\/Apr\/2016:00:00:01/,/\[9\/Apr\/2016:23:59:59/p' access.log |sort |uniq -c |sort -k1 -nr |head -n10  #前提开始时间与结束时间日志中必须存在
    4)统计当前时间前一分钟的访问数
        思路:先获取当前时间前一分钟对应日志格式的时间,再匹配统计
        $ date=$(date -d '-1 minute' +%d/%b/%Y:%H:%M);awk -vdate=$date '$0~date{c++}END{print c}' access.log
        $ date=$(date -d '-1 minute' +%d/%b/%Y:%H:%M);awk -vdate=$date '$4>="["date":00" && $4<="["date":59"{c++}END{print c}' access.log
        $ grep -c $(date -d '-1 minute' +%d/%b/%Y:%H:%M) access.log
        说明:date +%d/%b/%Y:%H:%M --> 09/Apr/2016:01:55
    5)统计访问最多的前10个页面($request)
        $ awk '{a[$7]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
    6)统计每个URL访问内容的总大小($body_bytes_sent)
        $ awk '{a[$7]++;size[$7]+=$10}END{for(i in a)print a[i],size[i],i}' access.log
    7)统计每个IP访问状态码数量($status)
        $ awk '{a[$1" "$9]++}END{for(i in a)print i,a[i]}' access.log
    8)统计访问状态码为404的IP及出现次数
        $ awk '{if($9~/404/)a[$1" "$9]++}END{for(i in a)print i,a[i]}' access.log
2、两个文件对比
    文件内容如下:
    $ cat a
    1
    2
    3
    4
    5
    6
    $ cat b
    3
    4
    5
    6
    7
    8
    1)找出相同记录
        方法1:$ awk 'FNR==NR{a[$0];next}($0 in a)' a b
        3
        4
        5
        6
        解释前,先看下FNR和NR区别:
        $ awk '{print NR,$0}' a b
        1 1
        2 2
        3 3
        4 4
        5 5
        6 6
        7 3
        8 4
        9 5
        10 6
        11 7
        12 8
        $ awk '{print FNR,$0}' a b
        1 1
        2 2
        3 3
        4 4
        5 5
        6 6
        1 3
        2 4
        3 5
        4 6
        5 7
        6 8
        可以看出NR是处理一行记录,编号就会加1,同时也可以看到awk将两个文件当成一个合并后的文件处理
        而FNR则是处理一行记录,编号也会加1,但是,处理到第二个文件时,编号重新计数

        说明:FNR和NR是内置变量。FNR==NR常用于对两个文件处理,这个例子可以理解为awk将两个文件当成一个文件处理。

        处理a文件时,FNR是等于NR的,条件为真,执行a[$0],next表达式,意思是将每条记录存放到a数组作为下标(无元素),next是跳出,类似于continue,不执行后面表达式。

        执行过程以此类推,直到处理b件时,FNR不等于NR(FNR重新计数是1,NR继续加1是7),条件为假,不执行后面a[$0],next表达式,直接执行($0 in a)表达式,这句意思是处理b文件第一条继续判断是否在a数组中,如果在则打印这条记录,以此类推。

        这样可能更好理解些:
        $ awk 'FNR==NR{a[$0]}NR>FNR{if($0 in a)print $0}' a b
        方法2:
        $ awk 'FNR==NR{a[$0]=1;next}(a[$0])' a b   #小括号可以不加
        $ awk 'FNR==NR{a[$0]=1;next}(a[$0]==1)' a b
        $ awk 'FNR==NR{a[$0]=1;next}{if(a[$0]==1)print}' a b
        $ awk 'FNR==NR{a[$0]=1}FNR!=NR&&a[$0]==1' a b

        说明:先要知道后面的a[$0]不是一个数组,而是通过下标(b文件每条记录)来访问a数组元素。如果a[b的一行记录]获取的a数组元素是1,则为真,也就是等于1,打印这条记录,否则获取不到元素,则为假。
        方法3:
        $ awk 'ARGIND==1{a[$0]=1}ARGIND==2&&a[$0]==1' a b
        $ awk 'FILENAME=="a"{a[$0]=1}FILENAME=="b"&&a[$0]==1' a b

        说明:ARGIND内置变量,处理文件标识符,第一个文件为1,第二个文件为2。FILENAME也是内置变量,表示输入文件的名字
        方法4:$ sort a b |uniq -d
        方法5:$ grep -f a b
    2)找不同记录(同上,取反)
        $ awk 'FNR==NR{a[$0];next}!($0 in a)' a b
        $ awk 'FNR==NR{a[$0]=1;next}!a[$0]' a b
        $ awk 'ARGIND==1{a[$0]=1}ARGIND==2&&a[$0]!=1' a b
        $ awk 'FILENAME=="a"{a[$0]=1}FILENAME=="b"&&a[$0]!=1' a b
        7
        8
        方法2:$ sort a b |uniq -d
        方法3:$ grep -vf a b
3、合并两个文件
    1)将d文件性别合并到c文件
        $ cat c
        zhangsan 100
        lisi 200
        wangwu 300
        $ cat d
        zhangsan man
        lisi woman

        方法1:$ awk  'FNR==NR{a[$1]=$0;next}{print a[$1],$2}' c d
        zhangsan 100  man
        lisi 200 woman
        wangwu 300 man

        方法2:$ awk  'FNR==NR{a[$1]=$0}NR>FNR{print a[$1],$2}' c d
        说明:NR==FNR匹配第一个文件,NR>FNR匹配第二个文件,将$1为数组下标

        方法3:$ awk 'ARGIND==1{a[$1]=$0}ARGIND==2{print a[$1],$2}' c d

    2)将a.txt文件中服务名称合并到一个IP中
    $ cat a.txt
    192.168.2.100 : httpd
    192.168.2.100 : tomcat
    192.168.2.101 : httpd
    192.168.2.101 : postfix
    192.168.2.102 : mysqld
    192.168.2.102 : httpd

    $ awk -F: -vOFS=":" '{a[$1]=a[$1] $2}END{for(i in a)print i,a[i]}' a.txt
    $ awk -F: -vOFS=":" '{a[$1]=$2 a[$1]}END{for(i in a)print i,a[i]}' a.txt

    192.168.2.100 : httpd  tomcat
    192.168.2.101 : httpd  postfix
    192.168.2.102 : mysqld  httpd
    说明:a[$1]=$2 第一列为下标,第二个列是元素,后面跟的a[$1]是通过第一列取a数组元素(服务名),结果是$1=$2 $2,并作为a数组元素。

    3)将第一行附加给下面每行开头
    $ cat a.txt
    xiaoli
    a 100
    b 110
    c 120

    $ awk 'NF==1{a=$0;next}{print a,$0}' a.txt
    $ awk 'NF==1{a=$0}NF!=1{print a,$0}' a.txt

    xiaoli  a 100
    xiaoli  b 110
    xiaoli  c 120

4、倒序列打印文本
    $ cat a.txt
    xiaoli   a 100
    xiaoli   b 110
    xiaoli   c 120
    $ awk '{for(i=NF;i>=1;i--){printf "%s ",$i}print s}' a.txt
    100 a xiaoli
    110 b xiaoli
    120 c xiaoli
    $ awk '{for(i=NF;i>=1;i--)if(i==1)printf $i"\n";else printf $i" "}' a.txt
    说明:利用NF降序输出,把最后一个域作为第一个输出,然后自减,print s或print ""打印一个换行符

5、从第二列打印到最后

    方法1:$ awk '{for(i=2;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i" "}' a.txt
    方法2:$ awk '{$1=""}{print $0}' a.txt
    a 100
    b 110
    c 120
6、将c文件中第一列放到到d文件中的第三列
    $ cat c
    a
    b
    c
    $ cat d
    1 one
    2 two
    3 three
    方法1:$ awk 'FNR==NR{a[NR]=$0;next}{$3=a[FNR]}1' c d
    说明:以NR编号为下标,元素是每行,当处理d文件时第三列等于获取a数据FNR(重新计数1-3)编号作为下标。
    方法2:$ awk '{getline f<"c";print $0,f}' d
    1 one a
    2 two b
    3 three c
    1)替换第二列
    $ awk '{getline f<"c";gsub($2,f,$2)}1' d
    1 a
    2 b
    3 c
    2)替换第二列的two
    $ awk '{getline f<"c";gsub("two",f,$2)}1' d
    1 one
    2 b
    3 three
7、数字求和
    方法1:$ seq 1 100 |awk '{sum+=$0}END{print sum}'
    方法2:$ awk 'BEGIN{sum=0;i=1;while(i<=100){sum+=i;i++}print sum}'
    方法3:$ awk 'BEGIN{for(i=1;i<=100;i++)sum+=i}END{print sum}' /dev/null
    方法4:$ seq -s + 1 100 |bc
8、每隔三行添加一个换行符或内容
    方法1:$ awk '$0;NR%3==0{printf "\n"}' a
    方法2:$ awk '{print NR%3?$0:$0"\n"}' a
    方法3:$ sed '4~3s/^/\n/' a
9、字符串拆分
    方法1:
    $ echo "hello" |awk -F '' '{for(i=1;i<=NF;i++)print $i}'
    $ echo "hello" |awk -F '' '{i=1;while(i<=NF){print $i;i++}}'
    h
    e
    l
    l
    o
    方法2:
    $ echo "hello" |awk '{split($0,a,"''");for(i in a)print a[i]}'  #无序
    l
    o
    h
    e
    l
10、统计字符串中每个字母出现的次数
    $ echo a,b.c.a,b.a |tr "[,. ]" "\n" |awk -F '' '{for(i=1;i<=NF;i++)a[$i]++}END{for(i in a)print i,a[i]|"sort -k2 -rn"}'
    a 3
    b 2
    c 1
11、第一列排序
    $ awk '{a[NR]=$1}END{s=asort(a,b);for(i=1;i<=s;i++){print i,b[i]}}' a.txt
    说明:以每行编号作为下标值为$1,并将a数组值放到数组b,a下标丢弃,并将asort默认返回值(原a数组长度)赋值给s,使用for循环小于s的行号,从1开始到数组长度打印排序好的数组。
12、删除重复行,顺序不变
    $ awk '!a[$0]++' file


13、删除指定行
    删除第一行:
    $ awk 'NR==1{next}{print $0}' file #$0可省略
    $ awk 'NR!=1{print}' file
    $ sed '1d' file
    $ sed -n '1!p' file
14、在指定行前后加一行
    在第二行前一行加txt:
    $ awk 'NR==2{sub('/.*/',"txt\n&")}{print}' a.txt
    $ sed'2s/.*/txt\n&/' a.txt
    在第二行后一行加txt:
    $ awk 'NR==2{sub('/.*/',"&\ntxt")}{print}' a.txt
    $ sed'2s/.*/&\ntxt/' a.txt
15、通过IP获取网卡名
    $ ifconfig |awk -F'[: ]' '/^eth/{nic=$1}/192.168.18.15/{print nic}'
16、浮点数运算(数字46保留小数点)
    $ awk 'BEGIN{print 46/100}'
    $ awk 'BEGIN{printf "%.2f\n",46/100}'
    $ echo 46|awk '{print $0/100}'
    $ echo 'scale=2;46/100' |bc|sed 's/^/0/'
    $ printf "%.2f\n" $(echo "scale=2;46/100" |bc)
    结果:0.46
17、替换换行符为逗号
    $ cat a.txt
    1
    2
    3
    替换后:1,2,3
    方法1:
    $ awk '{s=(s?s","$0:$0)}END{print s}' a.txt
    说明:三目运算符(a?b:c),第一个s是变量,s?s","$0:$0,第一次处理1时,s变量没有赋值初值是0,0为假,结果打印1,第二次处理2时,s值是1,为真,结果1,2。以此类推,小括号可以不写。
    方法2:
    $ tr '\n' ',' < a.txt
    方法3:
    $ sed ':a;N;s/\n/,/;$!b a' a.txt
    说明:第一个标签a,先读取第一行记录1追加到模式空间,此时模式空间内容是1$,执行$!b($!最后一行不跳转,b是控制流跳转命令)跳转到a标签,继续读取第二行记录2追加到模式空间,因为使用N命令,每个记录以换行符(\n)分割,此时模式空间内容是1\n2$,执行将换行符替换逗号命令,继续跳转到a标签...
    方法4:
    $ sed ':a;$!N;s/\n/,/;t a' a.txt
    说明:与上面类似,其中t是测试命令,当上一个命令(替换)执行成功才跳转。
    方法5:
    $ awk '{if($0!=3)printf "%s,",$0;else print $0}' a.txt
    说明:3是文本最后一个数
    方法6:
    while read line; do
        a+=($line)
    done < a.txt
    echo ${a[*]} |sed 's/ /,/g'
    说明:将每行放到数组,然后替换
18、把奇数换行符去掉
    $ cat b.txt
    string
    number
    a
    1
    b
    2
    $ awk 'ORS=NR%2?"\t":"\n"' b.txt  #把奇数行换行符去掉
    $ xargs -n2 < a.txt  #将两个字段作为一行
    string number
    a 1
    b 2
19、费用统计
    $ cat a.txt
    姓名             费用   数量
    zhangsan        8000    1
    zhangsan        5000    1
    lisi            1000    1
    lisi            2000    1
    wangwu          1500    1
    zhaoliu         6000    1
    zhaoliu         2000    1
    zhaoliu         3000    1
    统计每人总费用、总数量:
    $ awk '{name[$1]++;number[$1]+=$3;money[$1]+=$2}END{for(i in name)print i,number[i],money[i]}' a.txt
    zhaoliu 3 11000
    zhangsan 2 13000
    wangwu 1 1500
    lisi 2 3000
20、打印乘法口诀
    方法1:
    $ awk 'BEGIN{for(n=0;n++<9;){for(i=0;i++     1x2=2 2x2=4
    1x3=3 2x3=6 3x3=9
    1x4=4 2x4=8 3x4=12 4x4=16
    1x5=5 2x5=10 3x5=15 4x5=20 5x5=25
    1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
    1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
    1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
    1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81
    方法2:
    #!/bin/bash
    for ((i=1;i<=9;i++)); do
       for ((j=1;j<=i;j++)); do
         result=$(($i*$j))
         #let "result=i*j"
         echo -n "$i*$j=$result "
       done
       echo
    done
21、只打印奇数或偶数行
    打印奇数行:
    方法1:
    $ seq 1 5 |awk 'i=!i'
    说明:先知道对于数值运算,未定义变量初值为0,对于字符运算,未定义变量初值为空字符串。
    读取第一行记录,然后进行模式匹配,i是未定义变量,也就是i=!0,!取反意思。感叹号右边是个布尔值,0或空字符串为假,非0或非空字符串为真,!0就是真,因此i=1,条件为真打印第一条记录。
    没有print为什么会打印呢?因为模式后面没有动作,默认会打印整条记录。
    读取第二行记录,进行模式匹配,因为上次i的值由0变成了1,此时就是i=!1,条件为假不打印。
    读取第三行记录,因为上次条件为假,i恢复初值为0,继续打印。以此类推...
    可以看出,运算时并没有判断记录,而是利用布尔值真假判断。
    方法2:
    $ seq 1 5 |awk 'NR%2!=0'
    方法3:
    $ seq 1 5 |sed -n '1~2p'
    说明:步长,每隔一行打印一次
    方法4:
    $ seq 1 5 |sed -n 'p;n'
    说明:先打印第一行,执行n命令读取当前行的下一行2,放到模式空间,后面再没有打印模式空间行操作,所以只保存不打印,同等方式继续打印第三行。
    1
    3
    5
    打印偶数行:
    $ seq 1 5 |awk '!(i=!i)'
    $ seq 1 5 |awk 'NR%2==0'
    $ seq 1 5 |sed -n '0~2p'
    $ seq 1 5 |sed -n 'n;p'
    说明:读取当前行的下一行2,放到模式空间,使用p命令打印模式空间的行,输出2。

阅读(1876) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~