shell-awk語法整理
- 前言
- 基本語法
- 內置變量
- 1. $0
- 2. NF
- 3. NR
- 4. FS
- 5. RS
- 6. OFS
- 7. ORS
- 8. FILENAME
- 9. FNR
- 10. ARGV
- 11. ENVIRON
- 12. IGNORECASE
- 13. RSTART 和 RLENGTH
- 示例解釋
- 內置函數
- 循環語句(后面的';'可不加)
- 條件語句
- 高級特性
- 示例
- 特殊模式
- BEGIN
- END
- 組合示例
- BEGINFILE 和 ENDFILE
- getline 模式
- 總結
- 常用命令行選項
前言
AWK是一種功能強大的文本處理工具,可根據指定的規則對文本和數據文件進行逐行處理,通過靈活使用模式和動作的組合,可以實現復雜的文本分析和數據處理任務,適合處理各種格式的文本文件和數據流
基本語法
AWK的基本語法結構為:
awk pattern '{ action }' filename
- pattern:用來匹配輸入數據的模式
- action:在匹配到符合模式的行時執行的操作
- filename:要操作的目標文件
例如,要打印每行以字母 “a” 開頭的文本:
awk '/^a/ { print }' filename
其中,/^a/ 是模式,{ print } 是操作,會打印文件中所有以字母 “a” 開頭的行
內置變量
AWK 提供了許多內置變量,用于獲取關于輸入數據、當前行、行號等信息
1. $0
- 描述:代表當前行的內容
- 示例:打印所有行的內容(print后面什么都不帶,也是一樣的效果)
awk '{ print $0 }' filename
2. NF
- 描述:代表當前行的字段數
- 示例:打印每行的字段數
awk '{ print NF }' filename
3. NR
- 描述:代表當前行的行號
- 示例:打印每行的行號和內容
awk '{ print NR, $0 }' filename
4. FS
- 描述:代表字段分隔符,默認是空白字符
- 示例:使用不同的字段分隔符打印字段內容
awk -F':' '{ print $1, $2 }' filename
5. RS
- 描述:代表記錄分隔符,默認是換行符
- 示例:按不同的記錄分隔符處理數據
awk 'BEGIN { RS="@" } { print $0 }' filename
6. OFS
- 描述:代表輸出字段分隔符
- 示例:設置不同的輸出字段分隔符
awk 'BEGIN { OFS=" | " } { print $1, $2 }' filename
7. ORS
- 描述:代表輸出記錄分隔符
- 示例:設置不同的輸出記錄分隔符
awk 'BEGIN { ORS="\n\n" } { print $0 }' filename
8. FILENAME
- 描述:代表當前輸入文件的名稱
- 示例:打印當前處理的文件名
awk '{ print FILENAME }' filename
9. FNR
- 描述:代表當前處理的文件中的行號,從1開始計數
- 示例:打印當前處理的行號和內容
awk '{ print FNR, $0 }' filename
10. ARGV
- 描述:一個包含命令行參數的數組
- 示例:遍歷打印命令行參數
awk 'BEGIN { for (i = 0; i < ARGC; i++) print ARGV[i] }' file1 file2
11. ENVIRON
- 描述:一個包含環境變量的關聯數組
- 示例:打印所有環境變量及其值
awk 'BEGIN { for (var in ENVIRON) print var, ENVIRON[var] }'
12. IGNORECASE
- 描述:控制字符串匹配時是否忽略大小寫
- 示例:在匹配時忽略大小寫
awk 'BEGIN { IGNORECASE=1 } /pattern/ { print }' filename
13. RSTART 和 RLENGTH
- 描述:
- RSTART:上次 match() 函數匹配的起始位置
- RLENGTH:上次 match() 函數匹配的長度
- 示例:使用 match() 函數找到并打印匹配的子字符串及其位置
awk '{ if (match($0, /pattern/)) print "Found:", substr($0, RSTART, RLENGTH) }' filename
示例解釋
- $0:表示當前行的全部內容
- NF:表示當前行的字段數
- NR:表示當前行的行號
- FS:用于指定字段分隔符
- RS:用于指定記錄分隔符
- OFS:用于指定輸出字段分隔符
- ORS:用于指定輸出記錄分隔符
- FILENAME:用于輸入文件的名稱
- FNR:用于輸入當前處理的文件中的行號
- ARGV:輸出命令行參數的數組
- ENVIRON:輸出環境變量的關聯數組
- IGNORECASE:控制字符串匹配時是否忽略大小寫
- RSTART:上次 match() 函數匹配的起始位置
- RLENGTH:上次 match() 函數匹配的長度
內置函數
AWK 提供了多種內置函數,用于字符串處理、數學計算等
- 字符串函數:
- length(str):返回字符串長度
- index(str, search):返回搜索字符串在原字符串中的位置
- split(str, arr, sep):將字符串按分隔符分割成數組
- 數學函數:
- sin(x)、cos(x)、sqrt(x):三角函數和平方根函數
- rand():返回一個0到1之間的隨機數
循環語句(后面的’;'可不加)
AWK支持類C語言風格的循環語句:
- for循環:
for (i = 1; i <= 10; i++) {print i;
}
- while循環:
while (condition) {print $0;getline;
}
條件語句
AWK 中的條件語句與其他編程語言類似:
- if語句:
if (condition) {print "Condition is true";
} else {print "Condition is false";
}
- switch語句:
switch (variable) {case value1: {print "Value 1";break;}case value2: {print "Value 2";break;}default: {print "Default case";break;}
}
高級特性
AWK還支持更高級的特性,如函數定義、數組操作和模式動作的組合使用:
- 函數定義:
function add(x, y) {return x + y;
}
- 數組操作:
# 創建數組
arr["key1"] = "value1";
arr["key2"] = "value2";# 遍歷數組
for (key in arr) {print key, arr[key];
}
示例
演示了AWK的基本語法、內置變量、函數、循環和條件語句的使用:
# AWK script to print lines containing "error"
# and count lines where first field is numeric# Print lines containing "error"
/error/ {print;
}# Count lines where first field is numeric
$1 ~ /^[0-9]+$/ {count++;
}# END block to print count
END {print "Numeric lines count:", count;
}
特殊模式
BEGIN
-
描述:BEGIN 塊用于在處理任何輸入數據之前執行初始化任務,例如設置變量、打印標題、配置輸出格式等BEGIN 塊中的代碼在任何輸入數據處理之前運行一次
-
示例:打印表頭,并設置字段分隔符
awk 'BEGIN { OFS = "\t"; print "Name", "Age", "City" } { print $1, $2, $3 }' filename
示例中在處理 filename 文件之前,會打印表頭 “Name”, “Age”, “City”,并將輸出字段分隔符 (OFS) 設置為制表符
END
-
描述:END 塊用于在處理所有輸入數據之后執行任務,例如打印總結信息、計算總和或平均值等。END 塊中的代碼在所有輸入數據處理完后運行一次
-
示例:計算并打印行數
awk 'END { print "Total lines:", NR }' filename
示例中在處理完 filename 文件的所有行之后,打印總行數,其中 NR 是記錄數的內置變量,表示總行數
組合示例
可同時使用 BEGIN 和 END 塊來初始化和總結數據處理:
awk 'BEGIN { print "Processing file:", FILENAME } { sum += $2 } END { print "Total sum of second column:", sum }' filename
- BEGIN { print “Processing file:”, FILENAME }:在處理任何數據之前打印當前處理的文件名
- { sum += $2 }:處理每一行,將第二列的值累加到 sum 變量中
- END { print “Total sum of second column:”, sum }:在處理完所有數據后,打印第二列值的總和
BEGINFILE 和 ENDFILE
-
描述:
- BEGINFILE:在處理每個輸入文件之前執行一次
- ENDFILE:在處理每個輸入文件之后執行一次
-
示例:
awk 'BEGINFILE { print "Start processing", FILENAME }{ print $0 }ENDFILE { print "End processing", FILENAME }' file1 file2
示例會在處理每個輸入文件 file1 和 file2 前后分別打印處理開始和處理結束的消息
getline 模式
-
描述:
- getline 模式用于手動從輸入中讀取下一行并處理。可與條件和循環結構一起使用,以控制輸入數據的處理方式
-
示例:
awk '/pattern/ { print "Found:", $0 if (getline next_line > 0) { print "Next line:", next_line } }' filename
示例會在匹配到某個模式后,打印當前行和下一行的內容(如果存在)
總結
- BEGIN:特殊模式塊,用于在處理輸入數據之前執行初始化操作
- END:特殊模式塊,用于在處理完所有輸入數據后執行總結或清理操作
- BEGINFILE 和 ENDFILE:用于在處理每個輸入文件前后執行特定操作
- getline模式:允許在腳本執行過程中手動控制輸入行的讀取和處理方式
常用命令行選項
- -F separator
- 描述:指定字段分隔符。默認情況下,字段分隔符為任何空白字符序列
- 示例:
awk -F ',' '{ print $1 }' filename
-F ',' 指定逗號為字段分隔符,然后打印每行的第一個字段
- -v var=value
- 描述:設置 AWK 變量的值。可以在 AWK 腳本中使用 -v 選項來傳遞變量
- 示例:
awk -v threshold=50 '$1 > threshold { print $0 }' filename
示例中,定義了一個變量 threshold 并將其傳遞給 AWK 腳本,然后根據條件打印符合要求的行
- -f script-file
- 描述:從指定的文件中讀取 AWK 腳本
- 示例:
awk -f myscript.awk data.txt
示例中,AWK 將執行 myscript.awk 文件中的腳本來處理 data.txt 文件