手册原则:用到啥记录啥,不求全反求精。
管道过滤器模型:利用cat/head/tail/nl 等文件读取工具获取文本,通过 管道 ‘|’ 输入到文本处理工具 sed, awk 当中。
nl /etc/passwd | sed '2a hello world'
nl /etc/passwd | sed '2i hello world'
这里的nl 是输出带行号的文件内容, 数字2a(append)表示第二行后添加, 2i(insert)表示第二行前添加。
nl /etc/passwd | sed '2,5c No 2-5 number'
用逗号分割的2,5表示 第2-5行,c(cover)表示覆盖, 意思时2-5行的内容将被’No 2-5 number’ 覆盖。
nl /etc/passwd | sed -n '/root/p' #搜索并print
nl /etc/passwd | sed '/root/d' #搜索并delete
/root就是表示搜索包含’root’的行,紧接着的’/'后面是搜索到后要执行的动作,p(print)表示打印出来, d(delete)表示要删除。
注意:sed要适时加上-n选项, 表示只输出经过sed筛选处理的行,比如上面搜索并打印,如果不加-n会输出额外的内容。
nl /etc/passwd | sed -n '/root/{s/bash/blueshell/g;p}' #处理有root的行,将这些行的bash换成blueshell
-n 表示只输出经过处理的行, /root先把有root的行拿出来, '/‘后面跟着一系列动作(多个动作需要用中括号包起来,用;分割)。在这里s/{被替换}/{新值}/g 是一个替换动作,其中g表示全部替换。 然后’;'接着下一个动作是p,就是替换之后打印出来。
ifconfig
eth0 Link encap:Ethernet HWaddr 01:01:01:01:01:00
inet addr:111.111.111.111 Bcast:111.111.111.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:562 errors:0 dropped:0 overruns:0 frame:0
TX packets:1255 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:102895 (100.4 KiB) TX bytes:3014715 (2.8 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
想要获得etho 的ip地址,如何去做?
ifconfig eth0 | sed -n "/inet addr/{s/^.*addr://g;p}" | sed 's/Bcast.*$//g'
找到含inet addr的行,执行将 " ^.*addr " 换成空的动作并打印。 引号内内容是一个正则表达式,表示从开头到addr结尾的内容,恰好是inet addr:。 然后管道传递给下一个sed, 作用是把从Bcast到结尾的内容换成空。这样就只剩下IP地址了。
awk也是按行处理。 awk常用来:分割,统计,条件打印等。
cat /etc/passwd | awk -F ':' '{print $5}'
表示将文件的每一行内容按 ‘:’ 分割,并输出第5个内容。每一行都会被输出。
在此之前先了解一个常用的内置变量:
NR 表示行数, NF表示列数, FS分隔符。
cat /etc/passwd | awk -F ':' '{if(NR%2==0){print $5}}'
如果行号是偶数,打印按’:'分隔的第5个元素。
多个if else
cat /etc/passwd | awk -F ':' '{if (NR==1) {print $1;} else if (NR==2) {print $2} else {print $3}}'
awk -F ',' '{a+=$3}END{print a/NR}' staff.csv
将每一行的 $3加起来,最后求平均。
cat /etc/passwd | awk -F ':' '{for (i=1;i$i ];}} END{for(wd in a){print wd;}}'
awk自动会按行遍历问本,所以我们只需要定义列的循环逻辑就可以,这里将列的每一个单词加入到带有去重功能的a(是一个集合)当中。所有循环结束后(END), 把a中的内容循环打印出来。