TShopping

 找回密碼
 註冊
搜索
查看: 1121|回復: 0
打印 上一主題 下一主題

[CentOS] Linux awk 命令

[複製鏈接]
跳轉到指定樓層
1#
發表於 2022-5-17 15:57:50 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
 
Push to Facebook
AWK 是一種處理文本文件的語言,是一種強大的文本分析工具。
那首叫紅的叫AW 是因為其取了三位創始人K Aho,Peter Weinberg 和Brian Kernighan 的姓氏符號。
語法
  1. awk [选项参数] 'script' var=value file(s)

  2. awk [选项参数] -f scriptfile var=value file(s)
複製代碼

參數說明:
  • -F fs 或 --field-separator fs
    指定輸入文件折分隔符,fs 是一個字符串或者是一個正則表達式,如-F:。
  • -v var=value --asign var=value
    一個用戶定義變量。
  • -f scripfile 或 --file scriptfile
    從腳本文件中讀取awk命令。
  • -mfnnn對nnn設置最大限制nnn,-mr nnn
    對nnnawk設置最大限制,並且-mf選項配置在兩個限制範圍內記錄;mr nnnn的最大限制功能是Bell的擴展功能,這是Bell的最大擴展功能,標準awk中不適用。
  • -W compact 或者--compat,-W traditional 或者--traditional
    在終端模式下運行awk。gawk 的行為和標準的awk 完全一樣,所以所有的awk 擴展都被加載了。
  • -W copyleft 或 --copyleft,-W 打印版權或 --copyright
    簡短的版權信息。
  • -W 幫助或--幫助,-W 用法或--usage
    打印全部awk 選項和每個選項的簡短說明。
  • -W lint 或 --lint
    打印不能向傳統 unix 平台移植的結構的警告。
  • -W lint-old 或 --lint-old
    打印關於不能向傳統unix平台移植的結構的警告。
  • -W posix
    是一個空格鍵,打開密碼是一個空格。 *=不能代替^和^=;fflush無效。
  • -W re-interval 或 --re-inerval
    允許間隔正則表達式的使用,參考grep中的Poix字符類),如表達式[[:alpha:]]。
  • -W source program-text 或 --source program-text
    使用program-text作為源代碼,可與-f命令混用。
  • -W 版本或 --version
    打印錯誤報告信息的版本。


基本用法
log.txt 文本內容如下:
  1. 2 this is a test
  2. 3 Do you like awk
  3. This's a test
  4. 10 There are orange,apple,mongo
複製代碼

用法一:
  1. awk '{[pattern] action}' {filenames}   # 行匹配语句 awk '' 只能用单引号
複製代碼

實例:
  1. # 每行按空格或TAB分割,输出文本中的1、4项
  2. $ awk '{print $1,$4}' log.txt
  3. ---------------------------------------------
  4. 2 a
  5. 3 like
  6. This's
  7. 10 orange,apple,mongo
  8. # 格式化输出
  9. $ awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
  10. ---------------------------------------------
  11. 2        a
  12. 3        like
  13. This's
  14. 10       orange,apple,mongo
複製代碼

用法二:
  1. awk -F  #-F相当于内置变量FS, 指定分割字符
複製代碼

實例:
  1. # 使用","分割
  2. [        DISCUZ_CODE_30        ]nbsp; awk -F, '{print $1,$2}'   log.txt
  3. ---------------------------------------------
  4. 2 this is a test
  5. 3 Do you like awk
  6. This's a test
  7. 10 There are orange apple
  8. # 或者使用内建变量
  9. $ awk 'BEGIN{FS=","} {print $1,$2}'     log.txt
  10. ---------------------------------------------
  11. 2 this is a test
  12. 3 Do you like awk
  13. This's a test
  14. 10 There are orange apple
  15. # 使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割
  16. $ awk -F '[ ,]'  '{print $1,$2,$5}'   log.txt
  17. ---------------------------------------------
  18. 2 this test
  19. 3 Are awk
  20. This's a
  21. 10 There apple
複製代碼

用法三:
  1. awk -v  # 设置变量
複製代碼

實例:
  1. $ awk -va=1 '{print $1,$1+a}' log.txt
  2. ---------------------------------------------
  3. 2 3
  4. 3 4
  5. This's 1
  6. 10 11
  7. $ awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
  8. ---------------------------------------------
  9. 2 3 2s
  10. 3 4 3s
  11. This's 1 This'ss
  12. 10 11 10s
複製代碼

用法四:
  1. awk -f {awk脚本} {文件名}
複製代碼

實例:
  1. $ awk -f cal.awk log.txt
複製代碼



運算符
運算符
描述
= += -= *= /= %= ^= **=赋值
?:C条件表达式
||逻辑或
&&逻辑与
~ 和 !~匹配正则表达式和不匹配正则表达式
< <= > >= != ==关系运算符
空格连接
+ -加,减
* / %乘,除与求余
+ - !一元加,减和逻辑非
^ ***求幂
++ --增加或减少,作为前缀或后缀
$字段引用
in数组成员
過濾第一列大於2的行
  1. $ awk '$1>2' log.txt    #命令
  2. #输出
  3. 3 Do you like awk
  4. This's a test
  5. 10 There are orange,apple,mongo
複製代碼

過濾第一列2的行
  1. $ awk '$1==2 {print $1,$3}' log.txt    #命令
  2. #输出
  3. 2 is
複製代碼

過濾第一列大於2並且第二列類似'Are's的行
  1. $ awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt    #命令
  2. #输出
  3. 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)

  1. $ 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
  2. FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
  3. ---------------------------------------------
  4. log.txt    2    1         5    1
  5. log.txt    2    2         5    2
  6. log.txt    2    3         3    3
  7. log.txt    2    4         4    4
  8. $ 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
  9. FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
  10. ---------------------------------------------
  11. log.txt    2    1    '    1    1
  12. log.txt    2    2    '    1    2
  13. log.txt    2    3    '    2    3
  14. log.txt    2    4    '    1    4
  15. # 输出顺序号 NR, 匹配文本行号
  16. $ awk '{print NR,FNR,$1,$2,$3}' log.txt
  17. ---------------------------------------------
  18. 1 1 2 this is
  19. 2 2 3 Are you
  20. 3 3 This's a test
  21. 4 4 10 There are
  22. # 指定输出分割符
  23. [        DISCUZ_CODE_38        ]nbsp; awk '{print $1,$2,$5}' OFS=" $ "  log.txt
  24. ---------------------------------------------
  25. 2 $ this $ test
  26. 3 $ Are $ awk
  27. This's $ a $
  28. 10 $ There $
複製代碼


使用正則,字符串匹配
  1. # 输出第二列包含 "th",并打印第二列与第四列
  2. $ awk '$2 ~ /th/ {print $2,$4}' log.txt
  3. ---------------------------------------------
  4. this a
複製代碼

~ 表示模式開始。// 中是模式。
  1. # 输出包含 "re" 的行
  2. $ awk '/re/ ' log.txt
  3. ---------------------------------------------
  4. 3 Do you like awk
  5. 10 There are orange,apple,mongo
複製代碼


忽略大小寫
  1. $ awk 'BEGIN{IGNORECASE=1} /this/' log.txt
  2. ---------------------------------------------
  3. 2 this is a test
  4. This's a test
複製代碼


模式取反
  1. $ awk '$2 !~ /th/ {print $2,$4}' log.txt
  2. ---------------------------------------------
  3. Are like
  4. a
  5. There orange,apple,mongo
  6. $ awk '!/th/ {print $2,$4}' log.txt
  7. ---------------------------------------------
  8. Are like
  9. a
  10. There orange,apple,mongo
複製代碼


awk腳本
關於 awk 腳本,我們需要注意兩個關鍵詞 BEGIN 和 END。
  • BEGIN{裡面放的是執行前的語句這}
  • END {這裡面放的是處理完所有的行後要執行的語句}
  • {這裡面放的是處理每一行時要執行的語句}

假設有這麼一個文件(學生成績表):
  1. $ cat score.txt
  2. Marry   2143 78 84 77
  3. Jack    2321 66 78 45
  4. Tom     2122 48 77 71
  5. Mike    2537 87 97 95
  6. Bob     2415 40 57 62
複製代碼

              
我們的awk腳本如下:
  1. $ cat cal.awk
  2. #!/bin/awk -f
  3. #运行前
  4. BEGIN {
  5.     math = 0
  6.     english = 0
  7.     computer = 0

  8.     printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
  9.     printf "---------------------------------------------\n"
  10. }
  11. #运行中
  12. {
  13.     math+=$3
  14.     english+=$4
  15.     computer+=$5
  16.     printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
  17. }
  18. #运行后
  19. END {
  20.     printf "---------------------------------------------\n"
  21.     printf "  TOTAL:%10d %8d %8d \n", math, english, computer
  22.     printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
  23. }
複製代碼

我們來看一下執行結果:
  1. $ awk -f cal.awk score.txt
  2. NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
  3. ---------------------------------------------
  4. Marry  2143     78       84       77      239
  5. Jack   2321     66       78       45      189
  6. Tom    2122     48       77       71      196
  7. Mike   2537     87       97       95      279
  8. Bob    2415     40       57       62      159
  9. ---------------------------------------------
  10.   TOTAL:       319      393      350
  11. AVERAGE:     63.80    78.60    70.00
複製代碼

                                                                                                                                                                   
另外的一些實例
AWK的hello world程序為:
  1. BEGIN { print "Hello, world!" }
複製代碼

計算文件大小
  1. $ ls -l *.txt | awk '{sum+=$5} END {print sum}'
  2. --------------------------------------------------
  3. 666581
複製代碼

從文件中查詢長度大於80的行:
  1. awk 'length>80' log.txt
複製代碼

打印九九乘法表
  1. 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")}'
複製代碼
文章出處
https://www.runoob.com/linux/linux-comm-awk.html

 

臉書網友討論
*滑块验证:
您需要登錄後才可以回帖 登錄 | 註冊 |

本版積分規則



Archiver|手機版|小黑屋|免責聲明|TShopping

GMT+8, 2024-11-1 07:02 , Processed in 0.070075 second(s), 22 queries .

本論壇言論純屬發表者個人意見,與 TShopping綜合論壇 立場無關 如有意見侵犯了您的權益 請寫信聯絡我們。

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表