程式設計雜筆

[資工雜筆] awk 好用用法整理

抓放實驗的空檔,花時間從以下網址整理一些好用的 awk 用法,之後如果需要查的話也方便許多。這篇選出的每一個用法都不會放解釋 (沒時間QQ),解釋請參照 原網址來源 。廢話不多說,開始囉。

首先,如果有一個 file 長這個樣子:
Name Domain
Deepak Banking
Neha Telecom
Vijay Finance
Guru Migration

  1. 只把名字印出來
    $ awk ‘{print $1}’ file
    Name
    Deepak
    Neha
    Vijay
    Guru

  2. 把 header 拿掉
    $ awk 'NR!=1{print $1}' file
    Deepak
    Neha
    Vijay
    Guru

  3. 只印有 Deepak 的列
    $ awk '$0 ~ /Deepak/{print}' file
    Deepak Banking

  4. 印第一行不含 Deepak 的
    $ awk -F, '$1 !~ /Deepak/' file
    Name Domain
    Neha Telecom
    Vijay Finance
    Guru Migration

接著,如果有一個 file 長這個樣子
START
Unix
Linux
START
Solaris
Aix
SCO

  1. Join START 之後的列
    awk '/START/{if (NR!=1)print "";next}{printf $0}END{print "";}' file
    UnixLinux
    SolarisAixSCO

  2. 同 5 用逗號分開,事實上,上一篇就是用到這個用法
    awk '/START/{if (x)print x;x="";next}{x=(!x)?$0:x","$0;}END{print x;}' file
    Unix,Linux
    Solaris,Aix,SCO

如果接著有一個 file 長這個樣子
Item1,200
Item2,500
Item3,900
Item2,800
Item1,600

  1. 把第二行加總
    awk -F"," '{x+=$2}END{print x}' file
    3000

  2. 找 set($1)
    awk -F, '{a[$1];}END{for (i in a)print i;}' file
    Item1
    Item2
    Item3

  3. 把各 item 的數值連接起來
    awk -F, '{a[$1]=a[$1]?a[$1]":"$2:$2;}END{for (i in a)print i, a[i];}' OFS=, file
    Item1,200:600
    Item2,500:800
    Item3,900

  4. 以第一行值為檔名.txt分開各檔案
    awk -F, '{print > $1".txt"}' file

如果接著有一個 file 長這個樣子

HEADER
Unix
Linux
Solaris
AIX
SCO
TRAILER

  1. 每四列分一個檔案
    awk 'NR%4==1{x="F"++i;}{print > x}' file

$ cat F1
HEADER
Unix
Linux
Solaris

$ cat F2
AIX
SCO
TRAILER

  1. 每三列分一個檔案,排除 HEADER 和 TRAILER
    sed '1d;$d;' file | awk 'NR%3==1{x="F"++i;}{print > x}'

cat F1
Unix
Linux
Solaris

$ cat F2
AIX
SCO

  1. 每三列分一個檔案,每一個檔案都要有 HEADER 和 TRAILER
    awk 'BEGIN{getline f;}NR%3==2{x="F"++i;a[i]=x;print f>x;}{print > x}END{for(j=1;j<i;j++)print> a[j];}' file

$ cat F1
HEADER
Unix
Linux
Solaris
TRAILER

$ cat F2
HEADER
Aix
SCO
TRAILER

如果接著有一個 file 長這個樣子:
Item1:2010:10;20;30
Item2:2012:12;29;19
Item3:2014:15;50;61

  1. ungroup 每一列
    awk -F '[;:]' '{for(i=3;i<=5;i++){print $1,$2,$i;}}' OFS=":" file
    Item1:2010:10
    Item1:2010:20
    Item1:2010:30
    Item2:2012:12
    Item2:2012:29
    Item2:2012:19
    Item3:2014:15
    Item3:2014:50
    Item3:2014:61

如果接著有一個 file 長這個樣子:
123;abc[202];124
125;abc[203];124
127;abc[204];124

  1. 取出中括號裡的數
    awk -F '[][]' '{print $2}' file
    202
    203
    204

如果接著有一個 file 長這個樣子:
Unix,10,A
Linux,30,B
Solaris,40,C
Fedora,20,D
Ubuntu,50,E

  1. 在第一行插入列數
    awk -F, '{$1=++i FS $1;}1' OFS=, file
    1,Unix,10,A
    2,Linux,30,B
    3,Solaris,40,C
    4,Fedora,20,D
    5,Ubuntu,50,E

  2. 把第一行變大寫
    awk -F, '{$1=toupper($1)}1' OFS=, file
    UNIX,10,A
    LINUX,30,B
    SOLARIS,40,C
    FEDORA,20,D
    UBUNTU,50,E

  3. 第一行只取前3個字
    awk -F, '{$1=substr($1,0,3)}1' OFS=, file
    Uni,10,A
    Lin,30,B
    Sol,40,C
    Fed,20,D
    Ubu,50,E

廣告

發表迴響

Please log in using one of these methods to post your comment:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s