【大數據】05 文本處理

1、cut

Linux cut命令用於顯示每行從開頭算起 num1 到 num2 的文字。

語法

cut  [-bn] [file]
cut [-c] [file]
cut [-df] [file]

使用說明:

cut 命令從文件的每一行剪切字節、字符和字段並將這些字節、字符和字段寫至標準輸出。

如果不指定 File 參數,cut 命令將讀取標準輸入。必須指定 -b、-c 或 -f 標誌之一。

參數:

  • -b :以字節爲單位進行分割。這些字節位置將忽略多字節字符邊界,除非也指定了 -n 標誌。
  • -c :以字符爲單位進行分割。
  • -d :自定義分隔符,默認爲製表符。
  • -f :與-d一起使用,指定顯示哪個區域。
  • -n :取消分割多字節字符。僅和 -b 標誌一起使用。如果字符的最後一個字節落在由 -b 標誌的 List 參數指示的
    範圍之內,該字符將被寫出;否則,該字符將被排除
  • -s:不顯示沒有分隔符的行

實例

當你執行who命令時,會輸出類似如下的內容:

$ who
rocrocket :0           2009-01-08 11:07
rocrocket pts/0        2009-01-08 11:23 (:0.0)
rocrocket pts/1        2009-01-08 14:15 (:0.0)

如果我們想提取每一行的第3個字節,就這樣:

$ who|cut -b 3
c
c
c

2、sort

Linux sort命令用於將文本文件內容加以排序。

sort可針對文本文件的內容,以行爲單位來排序。

語法

sort [-bcdfimMnr][-o<輸出文件>][-t<分隔字符>][+<起始欄位>-<結束欄位>][--help][--verison][文件]

參數說明

  • -b 忽略每行前面開始出的空格字符。
  • -c 檢查文件是否已經按照順序排序。
  • -d 排序時,處理英文字母、數字及空格字符外,忽略其他的字符。
  • -f 排序時,將小寫字母視爲大寫字母。
  • -i 排序時,除了040至176之間的ASCII字符外,忽略其他的字符。
  • -m 將幾個排序好的文件進行合併。
  • -M 將前面3個字母依照月份的縮寫進行排序。
  • -n 依照數值的大小排序。
  • -o<輸出文件> 將排序後的結果存入指定的文件。
  • -r 以相反的順序來排序。
  • -t<分隔字符> 指定排序時所用的欄位分隔字符。
  • -k:選擇排序列
  • -u:合併相同行
  • +<起始欄位>-<結束欄位> 以指定的欄位來排序,範圍由起始欄位到結束欄位的前一欄位。
  • –help 顯示幫助。
  • –version 顯示版本信息。

實例

在使用sort命令以默認的式對文件的行進行排序,使用的命令如下:

sort testfile 

sort 命令將以默認的方式將文本文件的第一列以ASCII 碼的次序排列,並將結果輸出到標準輸出。

使用 cat命令顯示testfile文件可知其原有的排序如下:

$ cat testfile      #testfile文件原有排序  
test 30  
Hello 95  
Linux 85

使用sort命令重排後的結果如下:

$ sort testfile #重排結果  
Hello 95  
Linux 85  
test 30
[root@node0001 ~]# cat sort.txt 
banana 12
apple 8
orange 4
[root@node0001 ~]# sort -t' ' -k2 sort.txt 
banana 12
orange 4
apple 8
[root@node0001 ~]# sort -t' ' -k2 -n sort.txt 
orange 4
apple 8
banana 12
[root@node0001 ~]# sort -t' ' -k2 -nr sort.txt 
banana 12
apple 8
orange 4

3、wc

Linux wc命令用於計算字數。

利用wc指令我們可以計算文件的Byte數、字數、或是列數,若不指定文件名稱、或是所給予的文件名爲”-“,則wc指令會從標準輸入設備讀取數據。

語法

wc [-clw][--help][--version][文件...]

參數

  • -c或–bytes或–chars 只顯示Bytes數。
  • -l或–lines 只顯示列數。
  • -w或–words 只顯示字數。
  • –help 在線幫助。
  • –version 顯示版本信息。

實例

在默認的情況下,wc將計算指定文件的行數、字數,以及字節數。使用的命令爲:

wc testfile 

先查看testfile文件的內容,可以看到:

$ cat testfile  
Linux networks are becoming more and more common, but scurity is often an overlooked  
issue. Unfortunately, in today’s environment all networks are potential hacker targets,  
fro0m tp-secret military research networks to small home LANs.  
Linux Network Securty focuses on securing Linux in a networked environment, where the  
security of the entire network needs to be considered rather than just isolated machines.  
It uses a mix of theory and practicl techniques to teach administrators how to install and  
use security applications, as well as how the applcations work and why they are necesary.

使用 wc統計,結果如下:

$ wc testfile           # testfile文件的統計信息  
3 92 598 testfile       # testfile文件的行數爲3、單詞數92、字節數598 

其中,3 個數字分別表示testfile文件的行數、單詞數,以及該文件的字節數。

如果想同時統計多個文件的信息,例如同時統計testfile、testfile_1、testfile_2,可使用如下命令:

wc testfile testfile_1 testfile_2   #統計三個文件的信息 

輸出結果如下:

$ wc testfile testfile_1 testfile_2  #統計三個文件的信息  
3 92 598 testfile                    #第一個文件行數爲3、單詞數92、字節數598  
9 18 78 testfile_1                   #第二個文件的行數爲9、單詞數18、字節數78  
3 6 32 testfile_2                    #第三個文件的行數爲3、單詞數6、字節數32  
15 116 708 總用量                    #三個文件總共的行數爲15、單詞數116、字節數708 

我們可以注意到,每次使用 wc 命令統計文件信息之後,會打印文件名,我們可能有的時候需要將wc統計的內容賦值給變量又不希望帶上文件名,就可以使用 cat 組合一下:

$ cat testfile | wc     # testfile文件的統計信息  
3 92 598                # testfile文件的行數爲3、單詞數92、字節數598 

4、sed

Linux sed命令是利用script來處理文本文件。

sed可依照script的指令,來處理、編輯文本文件。

Sed主要用來自動編輯一個或多個文件;簡化對文件的反覆操作;編寫轉換程序等。

語法

sed [options] 'AddressCommand' file ...

參數[options] 說明:

  • -n: 靜默模式,不再默認顯示模式空間中的內容
  • -i: 直接修改原文件
  • -e SCRIPT -e SCRIPT:可以同時執行多個腳本
  • -f /PATH/TO/SED_SCRIPT
  • -r: 表示使用擴展正則表達式

Command

  • d: 刪除符合條件的
  • p: 顯示符合條件的行。通常 p 會與參數 sed -n 一起運行~
  • a \string: 在指定的行後面追加新,內容爲string
  •   \n:可以用於換行
  • i \string: 在指定的行前面添加新,內容爲string
  • r FILE: 將指定的文件的內容添加至符合條件的行處
  • w FILE: 將地址指定的範圍內的行另存至指定的文件中;
  • s/pattern/string/修飾符: 查找並替換,默認只替換每行中第一次被模式匹配到的字符串
  • g: 行內全局替換
  • i: 忽略字符大小寫
  • s///: s###, s@@@ 
  •  \(\), \1, \2

實例

在testfile文件的第四行後添加一行,並將結果輸出到標準輸出,在命令行提示符下輸入如下命令:

sed -e 4a\newLine testfile 

首先查看testfile中的內容如下:

$ cat testfile #查看testfile 中的內容  
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 

使用sed命令後,輸出結果如下:

$ sed -e 4a\newline testfile #使用sed 在第四行後添加新字符串  
HELLO LINUX! #testfile文件原有的內容  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test  
newline 

以行爲單位的新增/刪除

將 /etc/passwd 的內容列出並且列印行號,同時,請將第 2~5 行刪除!

[root@www ~]# nl /etc/passwd | sed '2,5d'
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
.....(後面省略).....

sed 的動作爲 ‘2,5d’ ,那個 d 就是刪除!因爲 2-5 行給他刪除了,所以顯示的數據就沒有 2-5 行羅~ 另外,注意一下,原本應該是要下達 sed -e 纔對,沒有 -e 也行啦!同時也要注意的是, sed 後面接的動作,請務必以 ” 兩個單引號括住喔!

只要刪除第 2 行

nl /etc/passwd | sed '2d'

要刪除第 3 到最後一行

nl /etc/passwd | sed '3,$d'

在第二行後(亦即是加在第三行)加上 drink tea 字樣!

[root@www ~]# nl /etc/passwd | sed '2a drink tea'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
drink tea
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
.....(後面省略).....

那如果是要在第二行前

nl /etc/passwd | sed '2i drink tea'

如果是要增加兩行以上,在第二行後面加入兩行字,例如 Drink tea or ….. 與 drink beer? 

[root@www ~]# nl /etc/passwd | sed '2a Drink tea or ......\
> drink beer ?'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea or ......
drink beer ?
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
.....(後面省略).....

每一行之間都必須要以反斜槓『 \ 』來進行新行的添加喔!所以,上面的例子中,我們可以發現在第一行的最後面就有 \ 存在。

以行爲單位的替換與顯示

將第2-5行的內容取代成爲『No 2-5 number』呢?

[root@www ~]# nl /etc/passwd | sed '2,5c No 2-5 number'
1 root:x:0:0:root:/root:/bin/bash
No 2-5 number
6 sync:x:5:0:sync:/sbin:/bin/sync
.....(後面省略).....

透過這個方法我們就能夠將數據整行取代了!

僅列出 /etc/passwd 文件內的第 5-7 行

[root@www ~]# nl /etc/passwd | sed -n '5,7p'
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
</p><p>
可以透過這個 sed 的以行爲單位的顯示功能, 就能夠將某一個文件內的某些行號選擇出來顯示。
</p>
<h3>數據的搜尋並顯示</h3>
<p>搜索 /etc/passwd有root關鍵字的行</p>
<pre>
nl /etc/passwd | sed '/root/p'
1  root:x:0:0:root:/root:/bin/bash
1  root:x:0:0:root:/root:/bin/bash
2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
3  bin:x:2:2:bin:/bin:/bin/sh
4  sys:x:3:3:sys:/dev:/bin/sh
5  sync:x:4:65534:sync:/bin:/bin/sync
....下面忽略

如果root找到,除了輸出所有行,還會輸出匹配行。

使用-n的時候將只打印包含模板的行。

nl /etc/passwd | sed -n '/root/p'
1  root:x:0:0:root:/root:/bin/bash

數據的搜尋並刪除

刪除/etc/passwd所有包含root的行,其他行輸出

nl /etc/passwd | sed  '/root/d'
2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
3  bin:x:2:2:bin:/bin:/bin/sh
....下面忽略
#第一行的匹配root已經刪除了

數據的搜尋並執行命令

搜索/etc/passwd,找到root對應的行,執行後面花括號中的一組命令,每個命令之間用分號分隔,這裏把bash替換爲blueshell,再輸出這行:

nl /etc/passwd | sed -n '/bash/{s/bash/blueshell/;p;q}'    
1  root:x:0:0:root:/root:/bin/blueshell

最後的q是退出。

數據的搜尋並替換

除了整行的處理模式之外, sed 還可以用行爲單位進行部分數據的搜尋並取代。基本上 sed 的搜尋與替代的與 vi 相當的類似!他有點像這樣:

sed 's/要被取代的字串/新的字串/g'

先觀察原始信息,利用 /sbin/ifconfig 查詢 IP

[root@www ~]# /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:90:CC:A6:34:84
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::290:ccff:fea6:3484/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
.....(以下省略).....

本機的ip是192.168.1.100。

將 IP 前面的部分予以刪除

[root@www ~]# /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g'
192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0

接下來則是刪除後續的部分,亦即: 192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0

將 IP 後面的部分予以刪除

[root@www ~]# /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast.*$//g'
192.168.1.100

多點編輯

一條sed命令,刪除/etc/passwd第三行到末尾的數據,並把bash替換爲blueshell

nl /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'
1  root:x:0:0:root:/root:/bin/blueshell
2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh

-e表示多點編輯,第一個編輯命令刪除/etc/passwd第三行到末尾的數據,第二條命令搜索bash替換爲blueshell。

直接修改文件內容(危險動作)

sed 可以直接修改文件的內容,不必使用管道命令或數據流重導向! 不過,由於這個動作會直接修改到原始的文件,所以請你千萬不要隨便拿系統配置來測試! 我們還是使用下載的 regular_express.txt 文件來測試看看吧!

利用 sed 將 regular_express.txt 內每一行結尾若爲 . 則換成 !

[root@www ~]# sed -i 's/\.$/\!/g' regular_express.txt

利用 sed 直接在 regular_express.txt 最後一行加入『# This is a test』

[root@www ~]# sed -i '$a # This is a test' regular_express.txt

由於 $ 代表的是最後一行,而 a 的動作是新增,因此該文件最後新增『# This is a test』!

sed 的『 -i 』選項可以直接修改文件內容,這功能非常有幫助!舉例來說,如果你有一個 100 萬行的文件,你要在第 100 行加某些文字,此時使用 vim 可能會瘋掉!因爲文件太大了!那怎辦?就利用 sed 啊!透過 sed 直接修改/取代的功能,你甚至不需要使用 vim 去修訂!

5、awk

AWK是一種處理文本文件的語言,是一個強大的文本分析工具。

相對於grep的查找,sed的編輯,awk在其對數據分析並生成報告時,顯得尤爲強大。

簡單來說awk就是把文件逐行的讀入,(空格,製表符)爲默認分隔符將每行切片,切開的部分再進行各種分析處理。

之所以叫AWK是因爲其取了三位創始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。

語法

awk [選項參數] 'script' var=value file(s)
或
awk [選項參數] -f scriptfile var=value file(s)

選項參數說明:

  • -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報告信息的版本。

基本用法

log.txt文本內容如下:

2 this is a test
3 Are you like awk
This's a test
10 There are orange,apple,mongo

用法一:

awk '{[pattern] action}' {filenames}   # 行匹配語句 awk '' 只能用單引號

實例:

# 每行按空格或TAB分割,輸出文本中的1、4項
 $ awk '{print $1,$4}' log.txt
 ---------------------------------------------
 2 a
 3 like
 This's
 10 orange,apple,mongo
 # 格式化輸出
 $ awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
 ---------------------------------------------
 2        a
 3        like
 This's
 10       orange,apple,mongo
 

用法二:

awk -F  #-F相當於內置變量FS, 指定分割字符

實例:

# 使用","分割
 $  awk -F, '{print $1,$2}'   log.txt
 ---------------------------------------------
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 # 或者使用內建變量
 $ awk 'BEGIN{FS=","} {print $1,$2}'     log.txt
 ---------------------------------------------
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 # 使用多個分隔符.先使用空格分割,然後對分割結果再使用","分割
 $ awk -F '[ ,]'  '{print $1,$2,$5}'   log.txt
 ---------------------------------------------
 2 this test
 3 Are awk
 This's a
 10 There apple

用法三:

awk -v  # 設置變量

實例:

 $ awk -va=1 '{print $1,$1+a}' log.txt
 ---------------------------------------------
 2 3
 3 4
 This's 1
 10 11
 $ awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
 ---------------------------------------------
 2 3 2s
 3 4 3s
 This's 1 This'ss
 10 11 10s

用法四:

awk -f {awk腳本} {文件名}

實例:

 $ awk -f cal.awk log.txt

運算符

運算符 描述
= += -= *= /= %= ^= **= 賦值
?: C條件表達式
|| 邏輯或
&& 邏輯與
~ ~! 匹配正則表達式和不匹配正則表達式
< <= > >= != == 關係運算符
空格 連接
+ – 加,減
* / % 乘,除與求餘
+ – ! 一元加,減和邏輯非
^ *** 求冪
++ — 增加或減少,作爲前綴或後綴
$ 字段引用
in 數組成員

過濾第一列大於2的行

$ awk '$1>2' log.txt    #命令
#輸出
3 Are you like awk
This's a test
10 There are orange,apple,mongo

過濾第一列等於2的行

$ awk '$1==2 {print $1,$3}' log.txt    #命令
#輸出
2 is

過濾第一列大於2並且第二列等於’Are’的行

$ awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt    #命令
#輸出
3 Are you

內建變量

變量 描述
\$n 當前記錄的第n個字段,字段間由FS分隔
\$0 完整的輸入記錄
ARGC 命令行參數的數目
ARGIND 命令行中當前文件的位置(從0開始算)
ARGV 包含命令行參數的數組
CONVFMT 數字轉換格式(默認值爲%.6g)ENVIRON環境變量關聯數組
ERRNO 最後一個系統錯誤的描述
FIELDWIDTHS 字段寬度列表(用空格鍵分隔)
FILENAME 當前文件名
FNR 各文件分別計數的行號
FS 字段分隔符(默認是任何空格)
IGNORECASE 如果爲真,則進行忽略大小寫的匹配
NF 輸入字段分割符
NR 已經讀出的記錄數,就是行號,從1開始
OFMT 數字的輸出格式(默認值是%.6g)
OFS 輸出記錄分隔符(輸出換行符),輸出時用指定的符號代替換行符
ORS 輸出記錄分隔符(默認值是一個換行符)
RLENGTH 由match函數所匹配的字符串的長度
RS 記錄分隔符(默認是一個換行符)
RSTART 由match函數所匹配的字符串的第一個位置
SUBSEP 數組下標分隔符(默認值是/034)
$ awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1         5    1
log.txt    2    2         5    2
log.txt    2    3         3    3
log.txt    2    4         4    4
$ awk -F\' 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1    '    1    1
log.txt    2    2    '    1    2
log.txt    2    3    '    2    3
log.txt    2    4    '    1    4
# 輸出順序號 NR, 匹配文本行號
$ awk '{print NR,FNR,$1,$2,$3}' log.txt
---------------------------------------------
1 1 2 this is
2 2 3 Are you
3 3 This's a test
4 4 10 There are
# 指定輸出分割符
$  awk '{print $1,$2,$5}' OFS=" $ "  log.txt
---------------------------------------------
2 $ this $ test
3 $ Are $ awk
This's $ a $
10 $ There $

使用正則,字符串匹配

# 輸出第二列包含 "th",並打印第二列與第四列
$ awk '$2 ~ /th/ {print $2,$4}' log.txt
---------------------------------------------
this a

~ 表示模式開始。// 中是模式。

# 輸出包含"re" 的行
$ awk '/re/ ' log.txt
---------------------------------------------
3 Are you like awk
10 There are orange,apple,mongo

忽略大小寫

$ awk 'BEGIN{IGNORECASE=1} /this/' log.txt
---------------------------------------------
2 this is a test
This's a test

模式取反

$ awk '$2 !~ /th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
$ awk '!/th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo

awk腳本

關於awk腳本,我們需要注意兩個關鍵詞BEGIN和END。

  • BEGIN{ 這裏面放的是執行前的語句 }
  • END {這裏面放的是處理完所有的行後要執行的語句 }
  • {這裏面放的是處理每一行時要執行的語句}

假設有這麼一個文件(學生成績表):

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

我們的awk腳本如下:

$ cat cal.awk
#!/bin/awk -f
#運行前
BEGIN {
    math = 0
    english = 0
    computer = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#運行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#運行後
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

我們來看一下執行結果:

$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350
AVERAGE:     63.80    78.60    70.00

另外一些實例

AWK的hello world程序爲:

BEGIN { print "Hello, world!" }

計算文件大小

$ ls -l *.txt | awk '{sum+=$6} END {print sum}'
--------------------------------------------------
666581

從文件中找出長度大於80的行

awk 'lengh>80' log.txt

打印九九乘法表

seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

統計報表:合計每人1月工資,0:manager,1:worker

文件內容如下:

[root@node0001 ~]# cat awk_label.txt 
Tom  0  2012-12-11  car  3000
John  1  2013-01-13  bike  1000
Vivi  1 2013-01-18  car  2800
Tom  0  2013-01-20  car  2500
John  1  2013-01-28  bike  3500

處理結果:

[root@node0001 ~]# awk   '{split($3,date,"-");if(date[2]=="01"){name[
$1]+=$5;if($2=="0"){role[$1]="M"}else{role[$1]="W"}}} END{for(i in name){print i "\t" name[i]"\t" role[i]}}' awk_label.txt

Tom    2500    M
John    4500    W
Vivi    2800    W
 

更多詳細內容可以查看 AWK 官方手冊:http://www.gnu.org/software/gawk/manual/gawk.

awk、sed、grep更適合的方向:

  •  grep 更適合單純的查找或匹配文本
  •  sed 更適合編輯匹配到的文本
  •  awk 更適合格式化文本,對文本進行較複雜格式處理

關於awk內建變量個人見解,簡單易懂

解釋一下變量:

變量:分爲內置變量和自定義變量;輸入分隔符FS和輸出分隔符OFS都屬於內置變量。

內置變量就是awk預定義好的、內置在awk內部的變量,而自定義變量就是用戶定義的變量。

  •  FS:輸入字段分隔符, 默認爲空白字符
  •  OFS:輸出字段分隔符, 默認爲空白字符
  •  RS:輸入記錄分隔符(輸入換行符), 指定輸入時的換行符
  •  ORS:輸出記錄分隔符(輸出換行符),輸出時用指定符號代替換行符
  •  NF:當前行的字段的個數(即當前行被分割成了幾列)
  •  NR:行號,當前處理的文本行的行號。
  •  FNR:各文件分別計數的行號
  •  ARGC:命令行參數的個數
  •  ARGV:數組,保存的是命令行所給定的各參數

自定義變量的方法

  •  方法一:-v varname=value ,變量名區分字符大小寫。
  •  方法二:在program中直接定義。

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章