awk純乾貨

AWK的驚人表現:html

Awk設計的目的:簡化通常文本處理的工做。程序員

屬於POSIX的一部分。正則表達式

 

AWK命令行:shell

Awk的調用能夠定義變量、提供程序而且指定輸入文件:express

 

  • Awk [ -F fs ]  [ -v var=value ... ] 'program' [ -- ] \
  • [ var=value ... ] [ file(s) ]
  • Awk [ -F fs ]  [ -v var=value ... ] -f program'file [ -- ] \
  • [ var=value ... ] [ file(s) ] 

 

短程序一般是直接在命令行上提供,而比較長的程序,則委託-f選項指定,遇到需鏈接被指名的程序文件以獲得完整的程序時,則可重複使用此選項,這是包含共享awk代碼的程序庫存之方便用法。選項需置於文件名以及通常var=value賦值的前面。數組

-- 是特殊選項:指出awk自己已沒有更進一步的命令行選項,任何接下來的選項均可被你的程序使用。函數

 

-f選項是用來從新定義默認字段分隔字符,且通常慣例將它做爲第一個命令行選項,緊接在-F選項後的fs參數是一個正則表達式,或是被提供做爲下一個參數。字段分隔字符也可設置使用內建變量FS所指定的:post

 

初始化的-v選項必須放在命令行上直接給定的任何程序以前,它們會在程序啓動以前以及處理任何文件以前生效,在一命令行程序以後的-v選項會被解釋爲一個文件名可(能是不存在的)spa

 

在命令行上其它地方的初始化會在處理參數時完成,而且會帶上文件名。例如:命令行

Awk '{ ... }' Pass=1 *.tex Pass=2 *.tex

處理文件的列表兩次,第一次是Pass設爲1,第二次將它設爲2.

注:使用字符串值進行初始化無須用引號框起來,除非shell要求這樣的引用,以保護牸字符或空白。支持正則。

注:特殊文件名-(連字號)表示標準輸入。/dev/stdin爲標準輸入,/dev/stderr標準錯誤輸出,/dev/stdout標準輸出。

 

Awk程序模型:

 

Awk把輸入流看做一連串記錄的集合,每條記錄均可進一步細分爲字段,一般,一行一條記錄,而字段則由一個或多個非空白字符的單詞組成。然而,是什麼構成一條記錄和一個字段,徹底是由程序員控制,且它們的定義,甚至能夠在處理期間更改。

一個awk程序是一對以模式(pattern)與大括號框起來的操做(action)組合而成的。

 

輸入會自動地由一個輸入文件切換到下一個,且awk自己一般會處理每一個輸入文件的打開、讀取和關閉,以容許用戶程序專心致力於記錄的處理。雖然模式多半是數據或字符串表達式,不過awk以保留字BEGINEND提供兩種特殊模式。

 

程序元素:awk處理數字與字符串數據,提供了標量(scalar)與數組(array)兩種變量以保存數據、數字與字符串表達式。還提供了一些語句類型以處理數據:賦值、註釋、條件、函數、輸入、循環及輸出。

 

#號註釋單行,單條語句多行可用反斜槓。

 

字符串的比較,用的是傳統的關係運算符。返回1爲真,0爲假。Awk並沒有特殊的字符串接續運算符。兩個連續字符串,會自動地鏈接在一塊兒。

 

支持正則表達式,有兩個運算符:~(匹配)與!~(不匹配)

 

正則表達式常量能夠用引號或斜槓加以定介:"ABC" ~ /^[A-Z]+$/ 等同於"ABC" ~ "^[A-Z]+$" ,若是在引號字符串里正好須要有字面意義的引號,則應以反斜槓("...\"...")保護。

 

Awk處理字符串轉數據的函數,s = "123" 接着n = 0  + s ,便將數據123賦值給n了。(並不適用)

 

Awk的數值運算符[


Awk可用括號以控制計算順序。

1、複合式,像/=這樣,以左邊運算數做爲右這的第一個去處數。N /=3 即是n=n/3

2、賦值的結果用來做爲另外一個表達式的部分表達式:(賦值運算符爲右結合性)

 

Awk裏通常經常使用到的內建標量變量


命令行參數

Awk對於命令行的自動化處理,awk經過內變量ARGC(參數計數)ARGV(參數向量,或參數值),讓命令行參數可用。

 

awk程序化模式中,經過輸入文件隱含循環的每一次迭代,會處理單一記錄(record),一般是一行文本,記錄可進一步再侵害爲更小的字符串,叫作字段(field)

 

FS的默認值爲單一空格,它接受特殊的解釋方式 。一個或多個空白字符(空格與製表字符)以及行的開頭與結尾的空白,都將被忽略。所以a b a        b相同。

----------------------------

[root@bogon 8csjb]# cat awkfs

a b c d

a        b        c        d        e        f

[root@bogon 8csjb]# awk -F" " '{print $1,$2,$3,$4,$5,$6}' awkfs

a b c d  

a b c d e f

--------------------------------------------------

匹配單個空格設置FS  = "[ ]"

 

字段能夠特殊名稱$1\$2...$NFawk程序使用。字段引用無須是固定的,有必須的話,它們還能夠轉換(經過截斷)爲整數值:假定k3,則值$k\$(1+2)$(27/9)、以及$3、都引用到第三個字段。特殊字段名稱$0引用到當前的記錄,初始值是從輸入流中讀取,且記錄分隔字符不是記錄的一部分。引用到0NF範圍以上的字段編號是不會有錯。

 

模式與操做構成awk程序的核心,awk的非傳統數據驅動程序模式,使得它更吸引用戶使用,也成就了許多awk程序的簡潔形式。

 

模式由字符串與或數值表達式構建而成:一昊它們計算出當前輸入記錄的值爲非零(真),則實行結合性的操做。若是模式是正則表達式,則意指此表達式會被來與整個輸入記錄進行匹配。

 

操做段落是可選地接在一個模式以後,也就是操做所在之處:它標明瞭如何處理該記錄。

 

常見用法:一個print語句裏包含了以逗號隔開的零或多個表達式,每一個表達式會被計算,有必要時會轉換爲一個字符串,且以輸出字段分隔字符OFS的值將輸出分隔後傳送到標準輸出,接在最後項目以後的是輸出記錄分隔字符ORS的值。

-------------------------------------------------------------------------------------------

[root@bogon ~]# echo '1 2 3 4 5 a' |awk '{ OFS ="abc"; print $1,$2,$3,$4,$5,$6}'

1abc2abc3abc4abc5abca

[root@bogon ~]# echo '1 2 3 4 5 a' |awk '{ OFS ="\n"; print $1,$2,$3,$4,$5,$6}'

1

2

3

4

5

a

[root@bogon ~]# echo '1 2 3 4 5 a' |awk '{ OFS =" "; print $1,$2,$3,$4,$5,$6}'

1 2 3 4 5 a

------------------------------------------------------------------------------------------------------

改變輸出字段分隔字符而沒有指定任何字段,不會改變$0;,若是咱們更改輸出字段分隔字符,並指定至少一個字段(即強制以新的字段分隔字符從新組合記錄)結果爲

[root@bogon ~]# echo '1 2 3 4 5 a' |awk '{ OFS ="\n";  print $0}'

1 2 3 4 5 a

[root@bogon ~]# echo '1 2 3 4 5 a' |awk '{ OFS ="\n"; $1=$1; print $0}'

1

2

3

4

5

A

----------------------------------------------------------------------

 

若是程序爲空,則awk不會讀取任何輸入並當即退出,因此咱們能夠匹配cat

除開NUL字符問題,awk能夠輕鬆取代cat

 

大量實例:

要將原始數值及它們的對數打印爲單欄的數據文件,可以使用:

Awk '{ print $1, log($1) }' file(s)

打印文本文件5%行左右的隨機樣本。使用虛擬承受機產行函數。

Awk 'rand() <0.05' file(s)

在以空白分隔字段的表格中,報告第n欄的和:

Awk -v COLUMN=n '{ sum += $COLUMN} END { print sum }' file(s)

------------------------------------------------------------------------------------

[root@bogon 8csjb]# echo "2" |awk -v COLUMN=n '{ sum += $COLUMN} END { print sum }'

2         #字符視爲0

[root@bogon 8csjb]# echo "2" |awk -v COLUMN=n '{ sum += $COLUMN} END { print sum/2 }'

1        #算術運算符

[root@bogon 8csjb]# awk '/print/' awk        #等同於grep 'print' awk

print "ARGC =", ARGC

print "ARGV[" k "] = [" ARGV[k] "]"

查找100-150

[root@bogon 8csjb]# awk '(1 <= FNR) && (FNR <=15) && /print/ {print FILENAME ":" FNR ":" $0 }' awk

awk:2:        print "ARGC =", ARGC

awk:4:        print "ARGV[" k "] = [" ARGV[k] "]"

sed以下:

[root@bogon 8csjb]# sed -n  1,15p -s awk |egrep 'print'

print "ARGC =", ARGC

print "ARGV[" k "] = [" ARGV[k] "]"

[root@bogon 8csjb]# awk 'BEGIN { FS = "print"; OFS = "&" } { $1=$1;print}' awk

BEGIN{

& "ARGC =", ARGC

for (k=0; k<ARGC; k++)

& "ARGV[" k "] = [" ARGV[k] "]"

}

刪除已排序流裏的重複行:

Sort file(s) |uniq

Sort file(s) | awk 'Last !=$0 { print } { Lst =$0 }'

將回車字符/換行字符的行終結,一致轉換爲以換行字符做爲行終結。

Sed -e 's/\r$//' file(s)

Sed -e 's/^M$//' file(s)        #^M ctrl+M

Mawk ''BEGIN { RS = "\r\n" } {print }' file(s)  

 

要將單空格的文本行,轉換爲雙空格的行。

-------------------------------------------------------------------------------------------------------

[root@bogon 8csjb]# sed -e 's/$/\n/' awk

BEGIN{

 

print "ARGC =", ARGC

 

for (k=0; k<ARGC; k++)

 

print "ARGV[" k "] = [" ARGV[k] "]"

 

}

[root@bogon 8csjb]# awk 'BEGIN { ORS = "\n\n"} {print}' awk         #記錄分隔符ORS

[root@bogon 8csjb]# awk 'BEGIN { ORS = "\n\n"} 1'  awk

[root@bogon 8csjb]# awk '{ print $0 "\n"}'   awk

[root@bogon 8csjb]# awk '{ print; print "" }'   awk

將雙空格行轉換爲單空格同樣是很容易的:

[root@bogon 8csjb]# awk '{ print; print "" }'   awk|awk 'BEGIN {RS ="\n *\n" } {print}'

BEGIN{

print "ARGC =", ARGC

for (k=0; k<ARGC; k++)

print "ARGV[" k "] = [" ARGV[k] "]"

}

尋找超過限制長度72個字符的行

egrep -n '^.{73,}' file(s)

[root@bogon 8csjb]# awk 'length($0) >3 {print FILENAME ":" FNR ":" $0 }' awk

awk:1:BEGIN{

awk:2:        print "ARGC =", ARGC

awk:3:        for (k=0; k<ARGC; k++)

awk:4:        print "ARGV[" k "] = [" ARGV[k] "]"

 

查找html標題內容

Awk -v ORS=' ' -v RS='( \n)' '/<title *>/, /<\/tiltle *>/' file(s) | sed -e '$@</title *> *@&\n@g'

煮酒品茶:能夠更新批量下載網頁那東西了,取標題頁。@/沒區別。特別環境特別使用。

 

語句:程序語言必須支持連續性的、條件式的及重複的執行。

連續執行如:a=1;b=2;c=3

條件式執行:

If (expression)

Statement1

Else

Statemnt2

 

重複執行whiledo) (forfor)

 

注意:由於浮點算術一般不精確,因此避免在for語句表達式裏,計算非整數的值。

 

其它的流程控制語句

只針對此記錄略過更進一步的模式檢查。

使用Next語句。

針對當前輸入文件略過更進一步的模式檢查。

Gawk與近期的nawk都提供nextfile語句,它會使得當前輸入文件當即關閉且模式的匹配會從命令行上下一個文件裏的記錄從新開始。

 

用戶控制的輸入

Awk直接處理命令行上標明的輸入文件,意指絕大多數的awk程序都沒必要本身打開與處理文件。它也能夠經過awkgetline語句來作這件事情。

 


awk支持重定向。


 

基礎數值函數



相關文章
相關標籤/搜索