日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gawk进阶

發布時間:2023/12/20 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gawk进阶 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如果對 gawk 不了解, 先閱讀 初識gawk 這篇博客.

1 使用變量

gawk 編程語言支持兩種不同類型的變量:

  • 內建變量
  • 自定義變量
  • 1.1 內建變量(built-in variables)

    查看 gawk 的所有內建變量, 可以通過 man gawk 然后搜索 Built-in Variables.

    這里列舉一些常用的內建變量:

    變量描述
    FIELDWIDTHS由空格分隔的一列數字, 定義了每個數據字段的確切寬度(field widths)
    FS輸入字段分隔符(input field separator, by default a space)
    RS輸入記錄分隔符(input record separator, by default a newline)
    OFS輸出字段分隔符(output field separator, by default a space)
    ORS輸出記錄分隔符(output record separator, by default a newline)
    ARGC當前命令行參數個數(argument count)
    ARGV當前命令行參數數組(argument values)
    FNR當前文件的記錄數(第幾行)(The input record number in the current input file)
    NF當前記錄的字段數(The number of fields in the current input record)
    ENVIRON由 shell 環境變量名和值組成的關聯數組(如, ENVIRON[“HOME”] 就是 shell 中的 $HOME)

    gawk 命令行參數 -F 和 內建變量 FS 的效果是一樣的.
    由 FS 分隔出來的 數據字段(用$1, $2等表示), $n 變量也屬于內建變量.

    看個例子幫助理解 FS 和 OFS:

    $ cat test.txt 11,12,13,14,15 21,22,23,24,25 31,32,33,34,35$ gawk 'BEGIN {FS=","} {print $1,$2,$3}' test.txt 11 12 13 21 22 23 31 32 33$ gawk 'BEGIN {FS=","; OFS="---"} {print $1,$2,$3}' test.txt 11---12---13 21---22---23 31---32---33

    FIELDWIDTHS 只適用于固定長度的字符串, 如果設置了 FIELDWIDTHS, gawk 會忽略 FS 變量, 并根據提供的 字段寬度 計算字段.
    示例:

    $ cat test.txt 1002.0301 1123.4007 6665.1239$ gawk 'BEGIN {FIELDWIDTHS="3 5 1"} {print $1, $2, $3}' test.txt 100 2.030 1 112 3.400 7 666 5.123 9

    使用 RS 示例:

    $ cat test.txt miyan xiao 木葉村 3組33號 15556928888rosie cui 魔都 上海中心100層 18806166000$ gawk 'BEGIN {FS="\n"; RS=""} {print $1, $3}' test.txt miyan xiao 15556928888 rosie cui 18806166000

    上面的數據比較特殊, 一組數據分散在多行(第1行是姓名, 第2行是地址, 第3行是電話; 不同組用空行分隔).
    要想把姓名和電話在一行輸出, 可以用 換行符\n 當做 FS, 用 空行"" 當做 RS.

    NF 表示 一個輸入記錄(input record, 默認是一行) 的字段個數, 我們可以用 $NF 獲取到最后一個字段:

    $ gawk 'BEGIN {FS=":"; OFS=":"} {print $1, $NF}' /etc/passwd root:/bin/bash bin:/sbin/nologin daemon:/sbin/nologin adm:/sbin/nologin ...

    1.2 自定義變量

    gawk 自定義的變量名可以是 字母, 數字 和 下劃線, 但不能以 數字 開頭.
    gawk 變量區分大小寫.

    gawk 賦值語句 不要求 = 左右沒有空格(shell 要求).
    示例:

    $ gawk 'BEGIN { test = "this is a test"; print test }' this is a test$ gawk 'BEGIN { test = "this is a test"; print test; quote> test = 45; print test }' this is a test 45$ gawk 'BEGIN { test = "this is a test"; print test; quote> test = 45; print test; quote> test = test * 2 + 1; print test}' this is a test 45 91

    和 shell 腳本一樣, gawk 變量不用指定數據類型, 一個變量既可以賦值 字符串 也可以賦值 數值.
    gawk 支持處理 數值 的標準操作符, 包括取余(%)和冪運算(^或**).

    2 處理數組

    關聯數組數字數組 不同之處在于它的 索引值 可以是任意文本字符串.
    關聯數組 更像是 散列表 或 字典.
    gawk 中的數組是 關聯數組.

    2.1 定義數組變量

    格式:

    var[index] = element

    var 是變量名, index 是索引值, element 是元素值.

    示例:

    $ gawk 'BEGIN { quote> names["mx"] = "miyan xiao" quote> print names["mx"] quote> }' miyan xiao

    2.2 遍歷數組變量

    可以使用 gawk 提供的 for-in 語句遍歷數組, 格式如下:

    for (var in array) {statements )

    示例:

    $ gawk 'BEGIN{ quote> vars["a"]=1 quote> vars["b"]=2 quote> for (i in vars){ quote> print "index:", i, " - value:", vars[i] quote> } quote> }' index: a - value: 1 index: b - value: 2

    擴展:
    可以使用 delete vars["a"] 刪除數組元素.

    3 使用模式

    gawk 支持多種類型的 匹配模式 來過濾數據記錄.

    3.1 正則表達式

    在使用正則時, 正則必須出現在 它要控制的程序腳本的 左花括號({) 前.

    正則匹配示例:

    $ cat test.txt 11,12,13 21,22,23 31,32,33$ gawk 'BEGIN {FS=","} /11/{print $0}' test.txt 11,12,13

    解釋:
    上面的 正則表達式 /11/ 是針對一條記錄(一行)做匹配的.

    3.2 匹配操作符

    匹配操作符(matching operator, 符號~) 可以指定 正則表達式 匹配指定的 數據字段變量($n).
    比如: $1 ~ /^data/ 表示 過濾出第一個字段($1) 以文本 data 開頭(/^data/)的所有記錄.

    ~ 讓正則表達式的對記錄的匹配更細粒度了(從一個記錄匹配到一個字段匹配).

    ~ 匹配字段 示例:

    $ cat test.txt 11,12,13 21,22,23 31,32,33$ gawk 'BEGIN {FS=","} $3 ~ /23$/{print $0}' test.txt 21,22,23

    表達式 $3 ~ /23$/ 可以匹配出 第三個字段($3) 以 23 結尾(23$)的所有記錄.

    再看一例:

    $ gawk -F: '$1 ~ /miyan/{print $1,$NF}' /etc/passwd miyan /bin/zsh

    擴展:
    可以使用 ! 來排除正則表達式的匹配.
    比如: $1 !~ /re/ 表示 如果記錄沒有匹配上正則 re, 程序腳本就會作用到該記錄.

    3.3 數學表達式

    除了正則, 也可以在 匹配模式 中使用 數學表達式.
    可以使用的數學表達式:==, <=,<,>=,>.

    顯示 所有屬于root用戶組(組ID為0) 的系統用戶:

    t$ gawk -F: '$4 == 0 {print $1}' /etc/passwd root sync shutdown halt operator

    4 結構化命令

    gawk 的結構化/控制 語句 和 Java 很類似, 這里從略.

    4.1 if

    4.2 while

    4.3 do-while

    4.4 for

    5 格式化打印

    print 命令在控制顯示數據的格式上能力有限.
    gawk 提供了 printf 格式化打印命令(accept the conversion specification formats).
    printf 命令的格式:

    printf "format_string", var1, var2 ...

    format_string 采用如下格式:
    %[modifier]control_letter

    control_letter 是控制字符, 控制字符 列表:

    控制字母描述
    c將一個數作為ASCII字符顯示(A single character.)
    d 和 i顯示一個整數值(A decimal number, the integer part)
    e用科學計數法顯示一個數(A floating point number of the form [-]d.dddddde[±]dd.)
    g科學計數法顯示, 相對于 e 更短(nonsignificant zeros suppressed)
    f顯示一個浮點值(A floating point number of the form [-]ddd.dddddd.)
    o顯示一個八進制值(An unsigned octal number)
    s顯示一個字符串(A character string.)
    x顯示一個十六進制值(An unsigned hexadecimal number)
    X顯示一個十六進制值, 使用 ABCDEF 而不是 abcdef

    除了控制字母 外, 還有 3 種 修飾符(modifier) 可以進一步控制輸出:

  • width: 指定 輸出字段最小寬度 的數字值. 如果輸出短于這個值, 用空格對齊; 如果長于這個值, 原樣輸出.
  • prec: precision 是一個數字值, 指定 浮點數小數點后的位數, 或者 字符串顯示的最大字符數.
  • -(減號): 采用左對齊而不是右對齊.
  • 結合 控制字符 和 修飾符, 可以得到 format_string 的完整格式如下:

    %[-][width][.prec]control_letter

    示例:

    $ gawk 'BEGIN{ printf "%s %s\n", "hello", "wold"}' hello wold

    注意: printf 不會自動添加換行, 上面我們手動添加了 \n 來換行.

    再看一例:

    $ gawk 'BEGIN{ printf "%-6.5s===%15s===%.3s \n", "123456789", "123456789", "123456789"}' 12345 === 123456789===123

    上面打印 3 個一樣的字符串(從1到9共9個字符);

    • %-6.5s 表示采用 左對齊(-), 字符串寬度(width)為6, 保留5個字符(prevision為5). 因為只有5個字符而寬度是6, 所以 12345 后面補充了一個 空格.
    • %15s 表示采用默認的右對齊, 字符串寬度(width)為15, 123456789 前面補充了6個空格.
    • %.3s 表示保留3個字符(prevision為3).

    6 內建函數

    gawk 支持一些常見的數學函數, 字符串函數, 時間函數.

    數學函數如下:
    指數函數, 自然對數, 平方根, 隨機數等等, 這里不做介紹.

    6.1 字符串函數

    gawk 支持的字符串處理函數如下(部分):

    函數描述
    asort(s [,d])將數組s 按數據 元素值排序. 索引值會被替換成新的排序順序的連續數字. 若指定了d, 則排序后的數組會被存儲在數組d 中
    asorti(s [,d])將數組s 按數據 索引值排序. 生成的數組會將索引值作為元素值, 用連續的數字索引來表明排序數學. 若指定了d, 則排序后的數組會被存儲在數組d 中
    index(s, t)返回字符串t 在字符串s 中的索引值, 沒找到返回0
    length([s])返回字符串s 的長度, 沒有指定字符串則返回 $0 的長度
    match(s, r [,a])返回字符串s 中 正則表達式r 出現的位置的索引. 如果指定了數組a, 它會存儲正則匹配到的那部分.
    split(s, a [, r])將s 用 FS 或正則r 分開放到數組 a 中, 返回字段的總和.
    sprintf(format, variables)參見上一節
    sub(r, s [, t])在變量$0 或 目標字符串t 中 查找正則r 的匹配. 如果找到了, 就用字符串s 替換掉第一處匹配
    substr(s, i [, n])返回 s 中從索引值i 開始的 n個字符組成的子串. 如果未提供n, 則返回s 剩下的部分
    tolower(s)s轉小寫
    toupper(s)s轉大寫

    示例:

    timeout 60 tail -f access.log | \awk '{c[substr($9, 1,1) "xx"]++; printf("\r2xx:%d 3xx:%d 4xx:%d 5xx:%d", c["2xx"],c["3xx"],c["4xx"],c["5xx"])}'

    access.log 是一個接口訪問的日志文件, 可以用上面的命令 監控60秒接口訪問返回的情況(有多少個2xx, 3xx, 4xx, 5xx http 狀態碼).
    狀態碼(2xx等) 放入關聯數組 c[] 中存儲.

    access.log 的一條示例:

    192.168.0.2 - - [08/Sep/2021:00:00:01 +0000] "GET /api/v1/about HTTP/1.0" 200 201 "-" "-" 2

    6.2 時間函數

    gawk 支持的時間函數:

    函數描述
    mktime(dataspec)將一個按 YYYY MM DD HH MM SS 格式指定的日期換成時間戳
    strftime(format [, timestamp])將當前時間的時間戳 或 指定的時間戳timestamp 轉化為格式化日期
    systime()當前時間的時間戳

    總結

    以上是生活随笔為你收集整理的gawk进阶的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。