awk純幹貨
AWK的驚人表現: Awk設計的目的:簡化一般文本處理的工作。 屬於POSIX的一部分。
AWK命令行: Awk的調用可以定義變量、提供程序並且指定輸入文件:
短程序通常是直接在命令行上提供,而比較長的程序,則委托-f選項指定,遇到需連接被指名的程序文件以得到完整的程序時,則可重復使用此選項,這是包含共享 -- 是特殊選項:指出awk本身已沒有更進一步的命令行選項,任何接下來的選項都可被你的程序使用。
-f選項是用來重新定義默認字段分隔字符,且一般慣例將它作為第一個命令行選項,緊接在-F選項後的fs參數是一個正則表達式,或是被提供作為下一個參數。字段分隔字符也可設置使用內建變量FS所指定的:
初始化的-v選項必須放在命令行上直接給定的任何程序之前,它們會在程序啟動之前以及處理任何文件之前生效,在一命令行程序之後的-v選項會被解釋為一個文件名可(能是不存在的)
在命令行上其它地方的初始化會在處理參數時完成,並且會帶上文件名。例如: Awk ‘{ ... }‘ Pass=1 *.tex Pass=2 *.tex 處理文件的列表兩次,第一次是Pass設為1,第二次將它設為2. 註:使用字符串值進行初始化無須用引號框起來,除非shell要求這樣的引用,以保護牸字符或空白。支持正則。 註:特殊文件名-(連字號)表示標準輸入。/dev/stdin為標準輸入,/dev/stderr標準錯誤輸出,/dev/stdout標準輸出。
Awk程序模型:
Awk把輸入流看作一連串記錄的集合,每條記錄都可進一步細分為字段,通常,一行一條記錄,而字段則由一個或多個非空白字符的單詞組成。然而,是什麽構成一條記錄和一個字段,完全是由程序員控制,且它們的定義,甚至可以在處理期間更改。 一個awk程序是一對以模式(pattern)與大括號框起來的操作(action)組合而成的。
輸入會自動地由一個輸入文件切換到下一個,且awk本身通常會處理每個輸入文件的打開、讀取和關閉,以允許用戶程序專心致力於記錄的處理。雖然模式多半是數據或字符串表達式,不過awk以保留字BEGIN與END提供兩種特殊模式。
程序元素:awk處理數字與字符串數據,提供了標量(scalar)與數組(array)兩種變量以保存數據、數字與字符串表達式。還提供了一些語句類型以處理數據:賦值、註釋、條件、函數、輸入、循環及輸出。
由#號註釋單行,單條語句多行可用反斜杠。
字符串的比較,用的是傳統的關系運算符。返回1為真,0為假。Awk並無特殊的字符串接續運算符。兩個連續字符串,會自動地連接在一起。
支持正則表達式,有兩個運算符:~(匹配)與!~(不匹配)
正則表達式常量可以用引號或斜杠加以定介:"ABC" ~ /^[A-Z]+$/ 等同於"ABC" ~ "^[A-Z]+$" ,如果在引號字符串裏正好需要有字面意義的引號,則應以反斜杠("...\"...")保護。
Awk處理字符串轉數據的函數,s = "123" 接著n = 0 + s ,便將數據123賦值給n了。(並不適用)
Awk的數值運算符[圖
Awk可用括號以控制計算順序。 一、復合式,像/=這樣,以左邊運算數作為右這的第一個去處數。N /=3 便是n=n/3 二、賦值的結果用來作為另一個表達式的部分表達式:(賦值運算符為右結合性)
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、...、$NF供awk程序使用。字段引用無須是固定的,有必須的話,它們還可以轉換(通過截斷)為整數值:假定k為3,則值$k\$(1+2)、$(27/9)、以及$3、都引用到第三個字段。特殊字段名稱$0引用到當前的記錄,初始值是從輸入流中讀取,且記錄分隔字符不是記錄的一部分。引用到0到NF範圍以上的字段編號是不會有錯。
模式與操作構成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
重復執行while、do) (for、for)
註意:因為浮點算術通常不精確,所以避免在for語句表達式裏,計算非整數的值。
其它的流程控制語句 只針對此記錄略過更進一步的模式檢查。 使用Next語句。 針對當前輸入文件略過更進一步的模式檢查。 Gawk與近期的nawk都提供nextfile語句,它會使得當前輸入文件立即關閉且模式的匹配會從命令行上下一個文件裏的記錄重新開始。
用戶控制的輸入 Awk直接處理命令行上標明的輸入文件,意指絕大多數的awk程序都不必自己打開與處理文件。它也可以通過awk的getline語句來做這件事情。
awk支持重定向。
基礎數值函數
來源: <http://bbs.magedu.com/thread-40-1-1.html> |
awk純幹貨