文本處理工具awk基礎用法

sed是以行爲單位的文本處理工具,awk則以列爲單位。

文件都是結構化的,都是有單詞和空白字符組成的。
空白字符包括空格、tab以及連續的空格和tab。每個非空白部分叫做域, $0表示 全部域, $1表示第1個域等等……

默認以空白字符爲分隔符,打印前兩列

fsj@ubuntu:~/templates$ cat data.txt 
a.wang  Male  30  021-11111111
b.yang  Female  25  021-22222222
c.liu Male  33  021-33333333
d.gong  Female  24  021-44444444

fsj@ubuntu:~/templates$ awk '{print $1,$2}' data.txt 
a.wang Male
b.yang Female
c.liu Male
d.gong Female

-F指定其他分割符,打印前兩列

fsj@ubuntu:~/templates$ awk -F. '{print $1,$2}' data.txt 
a wang  Male  30  021-11111111
b yang  Female  25  021-22222222
c liu Male  33  021-33333333
d gong  Female  24  021-44444444

內部變量NF表示每行有多少域

fsj@ubuntu:~/templates$ awk '{print NF}' data.txt 
4
4
4
4

同理,{print $NF}可以打印最後一個域,{print $NF-1}打印倒數第二域

截取字符串:substr(指定域, 子串開始位置, 子串結束位置)。不寫子串結束位置表示到末尾

內部變量length表示當前行的長度

fsj@ubuntu:~/templates$ cat data.txt | awk '{print substr($1,3)}'
wang
yang
liu
gong
fsj@ubuntu:~/templates$ cat data.txt | awk '{print substr($1,3)}' | awk '{print $NF,length}'
wang 4
yang 4
liu 3
gong 4

求數字列之和,並打印

fsj@ubuntu:~/templates$ cat data.txt | awk 'BEGIN{total=0}{total+=$3} END {print total}'
112

# total/行數
fsj@ubuntu:~/templates$ cat data.txt | awk 'BEGIN{total=0}{total+=$3}END{print total/NR}'
28

輸出行號

fsj@ubuntu:~/templates$ cat data1.txt
a wang  Male  30  021-11111111
b yang  Female  25  021-22222222
c liu Male  33  021-33333333

fsj@ubuntu:~/templates$ cat data1.txt | awk 'BEGIN{total=0}{total+=$3}END{print NF,NR}'
4 3

fsj@ubuntu:~/templates$ cat data1.txt | awk '{print NF,NR}'
4 1
4 2
4 3

實戰問題 1

文本中有多行數據,每一行可能有keyword,找出包含keyword的連續兩行行號

假設內容如下

fsj@ubuntu:~/tmp$ cat meitu.txt 
abc
66 kw
kw 4
d x
gdas
dsafd
ddd34
qq2

dtttt
kw3 kw kw
666666666666

kw
kw
theend

grep可以查到包含關鍵字kw的行

fsj@ubuntu:~/tmp$ grep kw meitu.txt -n
2:66 kw
3:kw 4
11:kw3 kw kw
14:kw
15:kw

如何查找連續兩行行號?

可以編寫腳本ctrow.sh,利用awk獲取行號列,然後判斷上一個kw所在行和當前kw所在行是否相差1

#!/bin/bash
pre=-100 # 上一個行號
for i in `grep kw meitu.txt -n | awk -F: '{print $1}'`
do
  if [ $((pre+1)) -eq $i ]; 
  then
      echo $i
  fi
  pre=$i
done

運行下:

fsj@ubuntu:~/tmp$ sh ctrow.sh 
3
15

補充,terminal下忽略文件名稱大小寫:
echo "set completion-ignore-case on" >> ~/.inputrc

References

  1. 王軍. Linux系統命令及Shell腳本實踐指南
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章