<sub id="gqw76"><listing id="gqw76"></listing></sub>
      <sub id="gqw76"><listing id="gqw76"></listing></sub>

    1. <form id="gqw76"><legend id="gqw76"></legend></form>
    2. Linux文本三劍客總結

      Linux文本處理三劍客

      grep

      文本過濾(模式:pattern)工具 grep, egrep, fgrep(不支持正則表達式搜索)

      grep

       grep: Global search REgular expression and Print out the line
       作用:文本搜索工具,根據用戶指定的“模式”對目標文本逐行進行匹配檢查;打印匹配到的行
       模式:由正則表達式字符及文本字符所編寫的過濾條件
       grep [OPTIONS] PATTERN [FILE...]
       grep root /etc/passwd
       grep "$USER" /etc/passwd
       grep '$USER' /etc/passwd
       grep `whoami` /etc/passwd

      grep命令選項

       --color=auto: 對匹配到的文本著色顯示
       -m # 匹配#次后停止
       -v 顯示不被pattern匹配到的行
       -i 忽略字符大小寫
       -n 顯示匹配的行號
       -c 統計匹配的行數
       -o 僅顯示匹配到的字符串
       -q 靜默模式,不輸出任何信息
       -A # after, 后#行
       -B # before, 前#行
       -C # context, 前后各#行
       -e 實現多個選項間的邏輯or關系
       grep –e ‘cat -e ‘dog’ file
       -w 匹配整個單詞
       -E 使用ERE
       -F 相當于fgrep,不支持正則表達式
       -f file 根據模式文件處理

      正則表達式

       REGEXP: Regular Expressions,由一類特殊字符及文本字符所編寫的模式,其中有些字符(元字符)不表示字符字面意義,而表示控制或通配的功能
       程序支持:grep,sed,awk,vim, less,nginx,varnish等
       分兩類:
       基本正則表達式:BRE
       擴展正則表達式:ERE
       grep -E, egrep
       正則表達式引擎:
       采用不同算法,檢查處理正則表達式的軟件模塊
       PCRE(Perl Compatible Regular Expressions)
       元字符分類:字符匹配、匹配次數、位置錨定、分組
       man 7 regex

      基本正則表達式元字符 字符匹配:

       . 匹配任意單個字符
       [] 匹配指定范圍內的任意單個字符,示例:[wang] [0-9] [a-z] [a-zA-Z]
       [^] 匹配指定范圍外的任意單個字符
       [:alnum:] 字母和數字
       [:alpha:] 代表任何英文大小寫字符,亦即 A-Z, a-z
       [:lower:] 小寫字母 [:upper:] 大寫字母
       [:blank:] 空白字符(空格和制表符)
       [:space:] 水平和垂直的空白字符(比[:blank:]包含的范圍廣)
       [:cntrl:] 不可打印的控制字符(退格、刪除、警鈴...
       [:digit:] 十進制數字 [:xdigit:]十六進制數字
       [:graph:] 可打印的非空白字符
       [:print:] 可打印字符
       [:punct:] 標點符號
       匹配次數:用在要指定次數的字符后面,用于指定前面的字符要出現的次數
       匹配前面的字符任意次,包括0次
       貪婪模式:盡可能長的匹配
       .* 任意長度的任意字符
       \? 匹配其前面的字符0或1次
       \+ 匹配其前面的字符至少1次
       \{n\} 匹配前面的字符n次
       \{m,n\} 匹配前面的字符至少m次,至多n次
       \{,n\} 匹配前面的字符至多n次
       \{n,\} 匹配前面的字符至少n次

      位置錨定:定位出現的位置

       ^ 行首錨定,用于模式的最左側
       $ 行尾錨定,用于模式的最右側
       ^PATTERN$ 用于模式匹配整行
       ^$ 空行
       ^[[:space:]]*$ 空白行
       \< \b 詞首錨定,用于單詞模式的左側
       \> \b 詞尾錨定,用于單詞模式的右側
       \<PATTERN\> 匹配整個單詞
       分組:\(\) 將一個或多個字符捆綁在一起,當作一個整體處理,如:\(root\)\+
       分組括號中的模式匹配到的內容會被正則表達式引擎記錄于內部的變量中,這些變量的命名方式為: \1, \2, \3, ...
       \1 表示從左側起第一個左括號以及與之匹配右括號之間的模式所匹配到的字符
       示例: \(string1\(string2\)\)
       \1 :string1\(string2\)
       \2 :string2
       后向引用:引用前面的分組括號中的模式所匹配字符,而非模式本身
       或者:\|
       示例:a\|b a或b
       C\|cat C或cat
       \(C\|c\)at Cat或cat

       

       

       

       

       

       

       

      練習題:

      1、顯示/proc/meminfo文件中以大小s開頭的行(要求:使用兩種方法)

       [root@shell ~]# grep -in '^s' /proc/meminfo 
       [root@shell ~]# cat /proc/meminfo |grep "^[sS]"
       cat /proc/meminfo | grep '^[sS]'  # 匹配開頭[sS]任意單個字符
       cat /proc/meminfo | grep '^[s\|S]'  # 匹配開頭s或者S
       grep '^s\|^S' /proc/meminfo   # 匹配開頭s或者開頭S
       grep -i '^s' /proc/meminfo  # 匹配開頭s忽略大小寫
      

      2、顯示/etc/passwd文件中不以/bin/bash結尾的行

       [root@shell ~]#cat /etc/passwd |grep -nv “/bin/bash$”
      

      3、顯示用戶rpc默認的shell程序

       cat /etc/passwd | grep -w '^root' | grep -o '[^/]\+$'
      

      4、找出/etc/passwd中的兩位或三位數

       grep "\b[0-9]\{2,3\}\b" /etc/passwd  # \b 詞首錨定,\b 詞尾錨定
       grep '\<[0-9]\{2,3\}\>' /etc/passwd  # \< 詞首錨定,\> 詞尾錨定
       grep -w '[0-9]\{2,3\}' /etc/passwd
       egrep -w '[0-9]{2,3}' /etc/passwd
      

      5、顯示CentOS7的/etc/grub2.cfg文件中,至少以一個空白字符開頭的且后面有非空白字符的行

       grep '^[[:space:]]\+[^[:graph:]]' /etc/grub2.cfg
       egrep '^[[:space:]]+[^[:graph:]]' /etc/grub2.cfg
      

      6、找出“netstat -tan”命令結果中以LISTEN后跟任意多個空白字符結尾的行

       netstat -tan | grep 'LISTEN[[:space:]]*$'
      

      7、顯示CentOS7上所有UID小于1000以內的用戶名和UID

       cut -d: -f 1,3 /etc/passwd | grep '\<[0-9]\{0,3\}\>'  # 匹配任意數字至少0個字符,至多3個字符
       cut -d: -f 1,3 /etc/passwd | grep '\b[0-9]\{0,3\}\b'
       cut -d: -f 1,3 /etc/passwd | grep -w '[0-9]\{0,3\}'
       cut -d: -f 1,3 /etc/passwd | egrep -w '[0-9]{0,3}'
       cut -d: -f 1,3 /etc/passwd | tr : ' ' | awk '{if($2<1000)print $1,$2}'| tr ' ' :
      

      8、添加用戶bash、testbash、basher、sh、nologin(其shell為/sbin/nologin),找出/etc/passwd用戶名和shell同名的行

      useradd bash && useradd testbash && useradd basher && useradd sh && useradd -s /sbin/nologin nologin
       cat /etc/passwd | grep '\(^[a-zA-Z0-9]\+\>\).*\<\1$'
       cat /etc/passwd | egrep '(^[[:alnum:]]+\>).*\<\1$'  
      
       # 匹配以任意數字或字母開頭的單詞至少一次,放入內置變量 \1,再匹配任意字符任意次直到結尾前一個單詞是 \1

      9、利用df和grep,取出磁盤各分區利用率,并從大到小排序

       df | grep ^/dev | grep -o '[0-9]\{1,\}%'|sort -nr  # -o 只顯示匹配的字符串
       df | grep ^/dev | egrep -o '[0-9]{1,}%'|sort -nr  # {1,} 匹配前一個字符至少1次
      

      egrep

      egrep及擴展的正則表達式

      egrep = grep -E egrep [OPTIONS] PATTERN [FILE...] 擴展正則表達式的元字符: 字符匹配: . 任意單個字符 [] 指定范圍的字符 [^] 不在指定范圍的字符

      擴展正則表達式

       次數匹配:
       .匹配前面字符任意次
       ? 0或1次
       + 1次或多次
       {m} 匹配m次
       {m,n} 至少m,至多n次
      

      擴展正則表達式 位置錨定:

       ^ 行首
       $ 行尾
       \<, \b 語首
       \>, \b 語尾
       分組:
       ()
       后向引用:\1, \2, ...
       或者:
       a|b a或b
       C|cat C或cat
       (C|c)at Cat或cat
      

      練習題:

      1、顯示三個用戶root、mage、wang的UID和默認shell

       cut -d: -f1,3,7 /etc/passwd | grep -w '^\(root\|mage\|wang\)'
       cut -d: -f1,3,7 /etc/passwd | egrep -w '^(root|mage|wang)'
      

      2、找出/etc/rc.d/init.d/functions文件中行首為某單詞(包括下劃線)后面跟一個小括號的行

       egrep -o '^.*\(\)' /etc/rc.d/init.d/functions
       grep -o '^[a-zA-Z0-9_].*()' /etc/rc.d/init.d/functions
       grep -o '^[[:alnum:]_].*()' /etc/rc.d/init.d/functions
      

      3、使用egrep取出/etc/rc.d/init.d/functions中其基名

       echo /etc/rc.d/init.d/functions | egrep -o '[^/]+$'
      
       # 從最后一個字符開始向前匹配,排除/至少一次后停止
       echo /etc/rc.d/init.d/functions | egrep -ow '[[:alnum:]]+$'
      

       # 從最后一個字符開始向前匹配,匹配到任意字母或數字組成的單詞至少一次后停止,基名不能有特殊字符

      4、使用egrep取出上面路徑的目錄名

       echo /etc/rc.d/init.d/functions | egrep -o  '.*/\<'
       root@shell ~]# echo /etc/rc.d/init.d/functions | egrep -o  '.*/\b'
       /etc/rc.d/init.d/
       [root@shell ~]# echo /etc/rc.d/init.d/functions | grep -o  '.*/\+\b'
       /etc/rc.d/init.d/
      

      5、統計last命令中以root登錄的每個主機IP地址登錄次數

       last | grep '^root' | awk '{print $1,$3}'| grep -v '[a-z]$'| sort | uniq -c
       # 篩選root登陸;篩選只顯示用戶和主機IP;排除沒有主機IP的行(不顯示以任意字母結尾的行);排序;統計
      last | grep ^root | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | sort | uniq -c
      
       # 篩選root登陸;篩選只顯示主機IP;排序;統計

      6、利用擴展正則表達式分別表示0-9、10-99、100-199、200-249、250-255

       echo {1..255} | egrep -wo '[0-9]' | tr "\n" " " ; echo
       echo {1..255} | egrep -wo '[1-9][0-9]' | tr "\n" " " ; echo
       echo {1..255} | egrep -wo '1[0-9]{2}' | tr "\n" " " ; echo
       echo {1..255} | egrep -wo '2[0-4][0-9]' | tr "\n" " " ; echo
       echo {1..255} | egrep -wo '25[0-5]' | tr "\n" " " ; echo
      

      7、顯示ifconfig命令結果中所有IPv4地址

       ifconfig | egrep -o "\<(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4]0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
      

      8、將此字符串:welcome to magedu linux 中的每個字符去重并排序,重復次數多的排到前面

       echo "welcome to magedu linux" | tr -d " " | egrep -o "." | sort | uniq -c | sort -nr
      
       # 刪除空格;拆分字符到每行(只顯示匹配到的任意字符的行);排序;去重;按第一行數字降序排序

      sed

      stream editor,文本編輯工具

      Stream EDitor, 行編輯器 sed是一種流編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩沖區中,稱為“模式空間”(pattern space),接著用sed命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕。然后讀入下行,執行下一個循環。如果沒有使諸如‘D’的特殊命令,那會在兩個循環之間清空模式空間,但不會清空保留空間。這樣不斷重復,直到文件末尾。文件內容并沒有改變,除非你使用重定向存儲輸出。 功能:主要用來自動編輯一個或多個文件,簡化對文件的反復操作,編寫轉換程序等 參考: http://www.gnu.org/software/sed/manual/sed.html

      sed工具

      用法:

       sed [option]... 'script' inputfile...
       常用選項:
       -n 不輸出模式空間內容到屏幕,即不自動打印
       -e 多點編輯
       -f /PATH/SCRIPT_FILE 從指定文件中讀取編輯腳本
       -r 支持使用擴展正則表達式
       -i.bak 備份文件并原處編輯
       script:
      
       '地址命令'

      地址定界:

       (1) 不給地址:對全文進行處理
       (2) 單地址:
       #:指定的行,$:最后一行
       /pattern/:被此處模式所能夠匹配到的每一行
       (3) 地址范圍:
       #,#
       #,+#
       /pat1/,/pat2/
       #,/pat1/
       (4) ~:步進
       1~2 奇數行
       2~2 偶數行
      

      編輯命令:

       d 刪除模式空間匹配的行,并立即啟用下一輪循環
       p 打印當前模式空間內容,追加到默認輸出之后
       a [\]text 在指定行后面追加文本,支持使用\n實現多行追加
       i [\]text 在行前面插入文本
       c [\]text 替換行為單行或多行文本
       w /path/file 保存模式匹配的行至指定文件
       r /path/file 讀取指定文件的文本至模式空間中匹配到的行后
       = 為模式空間中的行打印行號
       ! 模式空間中匹配行取反處理
      
       s/// 查找替換,支持使用其它分隔符,s@@@,s###
       替換標記:
       g 行內全局替換
       p 顯示替換成功的行
       w /PATH/FILE 將替換成功的行保存至文件中
      

      sed示例

       
      sed ‘2p’ /etc/passwd
       sed -n ‘2p’ /etc/passwd
       sed -n ‘1,4p’ /etc/passwd
       sed -n ‘/root/p’ /etc/passwd
       sed -n ‘2,/root/p’ /etc/passwd 從2行開始
       sed -n ‘/^$/=’ file 顯示空行行號
       sed -n -e ‘/^$/p’ -e ‘/^$/=’ file
       Sed‘/root/a\superman’ /etc/passwd行后
       sed ‘/root/i\superman’ /etc/passwd 行前
       sed ‘/root/c\superman’ /etc/passwd 代替行
       sed ‘/^$/d’ file
       sed ‘1,10d’ file
       nl /etc/passwd | sed ‘2,5d’
       nl /etc/passwd | sed ‘2a tea’
       sed 's/test/mytest/g' example
       sed –n ‘s/root/&superman/p’ /etc/passwd 單詞后
       sed –n ‘s/root/superman&/p’ /etc/passwd 單詞前
       sed -e ‘s/dog/cat/’ -e ‘s/hi/lo/’ pets
       sed –i.bak ‘s/dog/cat/g’ pets
       sed [options] 'script' inputfile...
       sed [options] -f scriptfile file(s)
           -e<script>,--expression=<script>    以指定的 script 來處理輸入的文件,用于順序執行多條命令
           -f<script 文件>,--file=<script 文件> 以指定的 script 文件來處理輸入的文件
           -n,--quiet,——silent                  取消自動打印模式空間
           -i[SUFFIX], --in-place[=SUFFIX]      直接編輯文件(如果提供后綴,則進行備份)
           -r                                   使用擴展正則表達式
       sed元字符集
       ^         匹配行開始,如:/^sed/匹配所有以sed開頭的行。
       $         匹配行結束,如:/sed$/匹配所有以sed結尾的行。
       .         匹配一個非換行符的任意字符,如:/s.d/匹配s后接一個任意字符,最后是d。
       *         匹配0個或多個字符,如:/*sed/匹配所有模板是一個或多個空格后緊跟sed的行。
       []        匹配一個指定范圍內的字符,如/[ss]ed/匹配sed和Sed。  
       [^]       匹配一個不在指定范圍內的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一個字母開頭,緊跟ed的行。
       \(..\)    匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替換成lovers。
       &         保存搜索字符用來替換其他字符,如s/love/**&**/,love這成**love**。
       \<        匹配單詞的開始,如:/\<love/匹配包含以love開頭的單詞的行。
       \>        匹配單詞的結束,如/love\>/匹配包含以love結尾的單詞的行。
       x\{m\}    重復字符x,m次,如:/0\{5\}/匹配包含5個0的行。
       x\{m,\}   重復字符x,至少m次,如:/0\{5,\}/匹配至少有5個0的行。
       x\{m,n\}  重復字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10個0的行。
       ?
       sed地址定界:默認對全文進行處理
       #              指定行
       $              最后一行
       /pattern/      被 pattern 匹配到的每一行
       #,#            區間
       #,+#           區間 +#=#+1
       /pat1/,/pat2/
       #,/pat1/
       first~step     步進(stepping) 先定位 first 所在行,然后每經過step行再定位一次
       1~2            奇數行
       2~2            偶數行
       first,~N       從 first 所在的行至往后第一個可以被N整除的行
       ?
       GNU擴展的sed,支持特殊序列(special sequence),它由一個反斜線和一個字母組成:
       \L:將replacement替換成小寫直到遇到\U或者\E。
       \l:將下一個字符替換成小寫。
       \U:將replacement替換成大寫直到遇到\L或者\E。
       \u:將下一個字符替換成大寫。
       \E:停止\U或者\L帶來的大小寫轉換功能。
       Examples:
       sed '2p' /etc/passwd                    打印文件內容,并重復打印文件第2行
       sed -n '2p' /etc/passwd                 只打印文件第2行
       sed -n '1,4p' /etc/passwd               只打印文件第1到4行
       sed -n '/root/p' /etc/passwd            只打印文件匹配 root 的行
       sed -n '2,/root/p' /etc/passwd          只打印文件從第2行開始到匹配 root 的行
       sed -n '/^$/=' file                     顯示空行行號(只打印文件匹配 ^$ 的行及其行號)
       sed -n -e '/^$/p' -e '/^$/=' file       只打印文件空行和空行及其行號
       sed '/root/a superman' /etc/passwd      匹配 root 的行后追加一行 superman
       sed '/root/i superman' /etc/passwd      匹配 root 的行前追加一行 superman
       sed '/root/c superman' /etc/passwd      用 superman 代替匹配 root 的行
       nl /etc/passwd | sed '2a tea'           文件第2行后追加一行 tea
       sed -n 's/root/&superman/p' /etc/passwd 只打印匹配 root 單詞后追加 superman 單詞的行
       sed -n 's/root/superman&/p' /etc/passwd 只打印匹配 root 單詞前追加 superman 單詞的行
       sed -i.bak 's/dog/cat/g' file           備份.bak 后,在原文件中替換并保存
       sed -i.bak 's/dog/cat/g' file           備份.bak 后,在原文件中替換并保存
       ?
       已匹配字符串標記&
       sed 's/\w\+/[&]/g' file      #  \w\+ 匹配每一個單詞
       替換操作:s命令
       sed 's/book/books/' file
       sed -n 's/test/TEST/p' file  # -n 抑制自動打印原文本,p 打印處理后的行。只打印發生替換的行
       刪除操作:d命令
       sed '/^$/d' file     刪除空白行
       sed '/^test/d' file  刪除文件中所有開頭是test的行
       sed '2d' file        刪除文件的第2行
       sed '$d' file        刪除文件最后一行
       sed '2,$d' file      刪除文件的第2行到末尾所有行
       地址定界:,(逗號)
       sed -n '/test/,/check/p' file     所有在模板test和check所確定的范圍內的行都被打印
       sed -n '5,/^test/p' file          打印從第5行開始到第一個包含以test開始的行之間的所有行:
       sed '/test/,/west/s/$/aaa/' file  模板test和west之間的行,每行的末尾用字符串aaa替換
       模式空間:
       sed '1!G;h;$!d' FILE ; sed -n '1!G;h;$p' FILE   倒序輸出(模擬tac)
       sed 'N;D' FILE ; sed '$!d' FILE         輸出文件最后一行
       sed '$!N;$!D' FILE                      輸出文件最后2行
       sed 'G' FILE                            給每行結尾添加一行空行
       sed 'g' FILE                            將文件全部行替換成空行
       sed 'N;s/\n//g' FILE                    將文件的n和n+1行合并為一行,n為奇數行
       sed ':a;N;$!ba;s/\n//g'                 將文件所有行合為一行
       sed '/^$/d;G' FILE                      刪除空白行后,給每行結尾添加一行空行
       sed 'n;d' FILE                          刪除偶數行
       sed -n 'p;n' test.txt  #奇數行
       sed -n 'n;p' test.txt  #偶數行
       sed '/test/{ n; s/aa/bb/; }' file 匹配test,移動到下一行,替換aa為bb,并打印該行
       ?
       打印匹配字符串的下一行
       grep -A 1 SCC URFILE
       sed -n '/SCC/{n;p}' URFILE
       awk '/SCC/{getline; print}' URFILE
       sed ':a;N;$!ba;s/\n//g' ; sed ':a;$!N;s/\n//g;ta'  將文件所有行合為一行
       :a         # 建立分支標記
       N          # 讀取下一行追加至模式空間
       $!ba       # 分支到腳本中帶有標記的地方
       s/\n//g    # 替換\n為空
      

      練習題

      1、刪除centos7系統/etc/grub2.cfg文件中所有以空白開頭的行行首的空白字符

       sed 's#[[:space:]]*##g' /etc/grub2.cfg
      

      2、刪除/etc/fstab文件中所有以#開頭,后面至少跟一個空白字符的行的行首的#和空白字符

       sed -r s/^#[[:space:]*// /etc/fstab
      

      3、在centos6系統/root/install.log每一行行首增加#號

       sed s/^Installing/#Installing/g /root/install.log
      

      4、在/etc/fstab文件中不以#開頭的行的行首增加#號

       sed -r "s/(^[^#])*/#\1/" /etc/fstab
      

      5、處理/etc/fstab路徑,使用sed命令取出其目錄名和基名

       基名:echo /etc/fstab | sed -r "s#^(/.*/)([^/]+/?)#\2#"
       目錄名:echo /etc/fstab | sed -r "s#^(/.*/)([^/]+/?)#\1#g"
      

      6、利用sed 取出ifconfig命令中本機的IPv4地址

       ifconfig ens33 |sed -n '2p' | sed -r "s/.*inet[[:space:]]*//" | sed -r "s/[[:space:]]*netmask.*//"
      

      7、統計centos安裝光盤中Package目錄下的所有rpm文件的以.分隔倒數第二個字段的重復次數

       ls /run/media/root/CentOS\ 7\ x86_64/Packages/ | grep -v "TBL" |sed -r "s#(.*\.([^.]+).rpm$)#\2#"
      

      8、統計/etc/init.d/functions文件中每個單詞的出現次數,并排序(用grep和sed兩種方法分別實現)

       grep方法:cat /etc/init.d/functions |grep -io "\<[[:alpha:]]*\>" |sort -rn |uniq -c |sort -n
       sed方法:sed "s/[^[:alpha:]]/\n/g" /etc/init.d/functions" | sort -rn | uniq -c |sort -n
      

      9、將文本文件的n和n+1行合并為一行,n為奇數行

       sed 'N;s/\n//'
      

      awk

      Linux上的實現gawk,文本報告生成器

      awk介紹 awk:Aho, Weinberger, Kernighan,報告生成器,格式化文本輸出 有多種版本:New awk(nawk),GNU awk( gawk) gawk:模式掃描和處理語言 基本用法: awk [options] 'program' var=value file… awk [options] -f programfile var=value file… awk [options] 'BEGIN{action;… }pattern{action;… }END{action;… }' file ... awk 程序可由:BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊,共3部分組成 program 通常是被放在單引號中 選項: -F “分隔符” 指明輸入時用到的字段分隔符 -v var=value 變量賦值

      awk語言

       基本格式:awk [options] 'program' file…
       Program:pattern{action statements;..}
       pattern和action
       ?pattern部分決定動作語句何時觸發及觸發事件
       BEGIN,END
       ?action statements對數據進行處理,放在{}內指明
       print, printf
       分割符、域和記錄
       ?awk執行時,由分隔符分隔的字段(域)標記$1,$2...$n稱為域標識。$0為所有域,注意:此時和shell中變量$符含義不同
       ?文件的每一行稱為記錄
       ?省略action,則默認執行 print $0 的操作

      awk工作原理

       第一步:執行BEGIN{action;… }語句塊中的語句
       第二步:從文件或標準輸入(stdin)讀取一行,然后執行pattern{ action;… }語句塊,它逐行掃描文件,從第一行到最后一行重復這個過程,直到文件全部被讀取完畢。
       第三步:當讀至輸入流末尾時,執行END{action;…}語句塊
       BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中
       END語句塊在awk從輸入流中讀取完所有的行之后即被執行,比如打印所有行的分析結果這類信息匯總都是在END語句塊中完成,它也是一個可選語句塊
       pattern語句塊中的通用命令是最重要的部分,也是可選的。如果沒有提供pattern語句塊,則默認執行{ print },即打印每一個讀取到的行,awk讀取的每一行都會執行該語句塊

      awk print格式:print item1, item2, ... 要點:

       (1) 逗號分隔符
       (2) 輸出item可以字符串,也可是數值;當前記錄的字段、變量或awk的表達式
       (3) 如省略item,相當于print $0
       示例:
       awk '{print "hello,awk"}'
       awk –F: '{print}' /etc/passwd
       awk –F: ‘{print “wang”}’ /etc/passwd
       awk –F: ‘{print $1}’ /etc/passwd
       awk –F: ‘{print $0}’ /etc/passwd
       awk –F: ‘{print $1”\t”$3}’ /etc/passwd
       grep “^UUID”/etc/fstab | awk ‘{print $2,$4}’
      

      awk變量 變量:內置和自定義變量

       FS:輸入字段分隔符,默認為空白字符
       awk -v FS=':' '{print $1,FS,$3}’ /etc/passwd
       awk –F: '{print $1,$3,$7}’ /etc/passwd
       OFS:輸出字段分隔符,默認為空白字符
       awk -v FS=‘:’ -v OFS=‘:’ '{print $1,$3,$7}’ /etc/passwd
       RS:輸入記錄分隔符,指定輸入時的換行符
       awk -v RS=' ' ‘{print }’ /etc/passwd
       ORS:輸出記錄分隔符,輸出時用指定符號代替換行符
       awk -v RS=' ' -v ORS='###'‘{print }’ /etc/passwd
       NF:字段數量
       awk -F:‘{print NF}’ /etc/fstab 引用變量時,變量前不需加$
       awk -F:‘{print $(NF-1)}' /etc/passwd
       NR:記錄號
       awk ‘{print NR}’ /etc/fstab ; awk END‘{print NR}’ /etc/fstab
      
       FNR:各文件分別計數,記錄號
       awk '{print FNR}' /etc/fstab /etc/inittab
       FILENAME:當前文件名
       awk '{print FILENAME}’ /etc/fstab
       ARGC:命令行參數的個數
       awk '{print ARGC}’ /etc/fstab /etc/inittab
       awk ‘BEGIN {print ARGC}’ /etc/fstab /etc/inittab
       ARGV:數組,保存的是命令行所給定的各參數
       awk ‘BEGIN {print ARGV[0]}’ /etc/fstab /etc/inittab
       awk ‘BEGIN {print ARGV[1]}’ /etc/fstab /etc/inittab
      
       自定義變量(區分字符大小寫)
       (1) -v var=value
       (2) 在program中直接定義
       示例:
       awk -v test='hello gawk' '{print test}' /etc/fstab
       awk -v test='hello gawk' 'BEGIN{print test}'
       awk 'BEGIN{test="hello,gawk";print test}'
       awk -F:‘{sex=“male”;print $1,sex,age;age=18}’ /etc/passwd
       cat awkscript
       {print script,$1,$2}
       awk -F: -f awkscript script=“awk” /etc/passwd
      
       printf命令
       格式化輸出:printf “FORMAT”, item1, item2, ...
       (1) 必須指定FORMAT
       (2) 不會自動換行,需要顯式給出換行控制符,\n
       (3) FORMAT中需要分別為后面每個item指定格式符
       格式符:與item一一對應
       %c:顯示字符的ASCII碼
       %d, %i:顯示十進制整數
       %e, %E:顯示科學計數法數值
       %f:顯示為浮點數
       %g, %G:以科學計數法或浮點形式顯示數值
       %s:顯示字符串
       %u:無符號整數
       %%:顯示%自身
       修飾符
      
       #[.#] 第一個數字控制顯示的寬度;第二個#表示小數點后精度,%3.1f
       - 左對齊(默認右對齊) %-15s
       + 顯示數值的正負符號 %+d
       printf示例
       awk -F: ‘{printf "%s",$1}’ /etc/passwd
       awk -F: ‘{printf "%s\n",$1}’ /etc/passwd
       awk -F: '{printf "%-20s %10d\n",$1,$3}' /etc/passwd
       awk -F:‘ {printf "Username: %s\n",$1}’ /etc/passwd
       awk -F: ‘{printf “Username: %s,UID:%d\n",$1,$3}’ /etc/passwd
       awk -F: ‘{printf "Username: %15s,UID:%d\n",$1,$3}’ /etc/passwd
       awk -F: ‘{printf "Username: %-15s,UID:%d\n",$1,$3}’ /etc/passwd
      
       操作符
       算術操作符:
       x+y, x-y, x*y, x/y, x^y, x%y
       - x:轉換為負數
       +x:將字符串轉換為數值
       字符串操作符:沒有符號的操作符,字符串連接
       賦值操作符:
       =, +=, -=, *=, /=, %=, ^=,++, --
       下面兩語句有何不同
       ?awk ‘BEGIN{i=0;print ++i,i}’
       ?awk ‘BEGIN{i=0;print i++,i}’
      

      操作符

       比較操作符:
       ==, !=, >, >=, <, <=
       模式匹配符:
       ~:左邊是否和右邊匹配,包含
       !~:是否不匹配
       示例:
      awk -F: '$0 ~ /root/{print $1}‘ /etc/passwd
       awk '$0~“^root"' /etc/passwd
       awk '$0 !~ /root/‘ /etc/passwd
       awk -F: ‘$3==0’ /etc/passwd
      
       邏輯操作符:與&&,或||,非!
       示例:
       ?awk -F: '$3>=0 && $3<=1000 {print $1}' /etc/passwd
       ?awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd
       ?awk -F: ‘!($3==0) {print $1}' /etc/passwd
       ?awk -F: ‘!($3>=500) {print $3}’ /etc/passwd
      
       條件表達式(三目表達式)
       selector?if-true-expression:if-false-expression
       ?示例:
       awk -F: '{$3>=1000?usertype="Common User":usertype=" SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
       PATTERN:根據pattern條件,過濾匹配的行,再做處理
       (1)如果未指定:空模式,匹配每一行
       (2) /regular expression/:僅處理能夠模式匹配到的行,需要用/ /括起來
       awk '/^UUID/{print $1}' /etc/fstab
       awk '!/^UUID/{print $1}' /etc/fstab
      
       (3) relational expression: 關系表達式,結果為“真”才會被處理
       真:結果為非0值,非空字符串
       假:結果為空字符串或0值
       示例:
       awk -F: 'i=1;j=1{print i,j}' /etc/passwd
       awk ‘!0’ /etc/passwd ; awk ‘!1’ /etc/passwd
       Awk -F: '$3>=1000{print $1,$3}' /etc/passwd
       awk -F: '$3<1000{print $1,$3}' /etc/passwd
       awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
       awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd
      

      awk PATTERN

        line ranges:行范圍
       startline,endline:/pat1/,/pat2/ 不支持直接給出數字格式
       awk -F: ‘/^root\>/,/^nobody\>/{print $1}' /etc/passwd
       awk -F: ‘(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
       BEGIN/END模式
       BEGIN{}:僅在開始處理文件中的文本之前執行一次
       END{}:僅在文本處理完成之后執行一次
      
       awk -F : ‘BEGIN {print “USER USERID”} {print $1“:”$3}
       END{print “END FILE"}' /etc/passwd
       awk -F : '{print "USER USERID“;print $1":"$3} END{print "END FILE"}' /etc/passwd
       awk -F: 'BEGIN{print " USER UID \n--------------- "}{print $1,$3}' /etc/passwd
       awk -F: ‘BEGIN{print “ USER UID \n--------------- ”}{print $1,$3}’END{print “==============”} /etc/passwd
       seq 10 | awk 'i=0'
       seq 10 | awk 'i=1'
       seq 10 | awk 'i=!i'
       seq 10 | awk '{i=!i;print i}'
       seq 10 | awk ‘!(i=!i)'
       seq 10 |awk -v i=1 'i=!i'
      

      awk action 常用的action分類

       (1) Expressions:算術,比較表達式等
       (2) Control statements:if, while等
       (3) Compound statements:組合語句
       (4) input statements
       (5) output statements:print等

      awk控制語句

       { statements;… } 組合語句
       if(condition) {statements;…}
       if(condition) {statements;…} else {statements;…}
       while(conditon) {statments;…}
       do {statements;…} while(condition)
       for(expr1;expr2;expr3) {statements;…}
       break
       continue
       delete array[index]
       delete array
       exit
      

      awk控制語句if-else 語法:if(condition){statement;…}[else statement] if(condition1){statement1}else if(condition2){statement2}else{statement3} 使用場景:對awk取得的整行或某個字段做條件判斷 示例:

       awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd
       awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
       awk '{if(NF>5) print $0}' /etc/fstab
       awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd
       awk -F: '{if($3>=1000) printf "Common user: %s\n",$1; else printf "root or Sysuser: %s\n",$1}' /etc/passwd
       df -h|awk -F% '/^\/dev/{print $1}'|awk '$NF>=80{print $1,$5}‘
       awk ‘BEGIN{ test=100;if(test>90){print “very good“}
       else if(test>60){ print ”good”}else{print “no pass”}}’
      

      while循環 語法:while(condition){statement;…} 條件“真”,進入循環;條件“假”,退出循環 使用場景: 對一行內的多個字段逐一類似處理時使用 對數組中的各元素逐一處理時使用 示例:

       awk '/^[[:space:]]*linux16/{i=1;while(i<=NF)
       {print $i,length($i); i++}}' /etc/grub2.cfg
       awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10) {print $i,length($i)}; i++}}’ /etc/grub2.cfg
       [root@shell ~]# echo I am oldboy teacher welcome to oldboy training class|awk '{for(i=1;i<=NF;i++){if (length($i)<=6) {print $i}}}' 
       I
       am
       oldboy
       to
       oldboy
       class
      
       do-while循環
       語法:do {statement;…}while(condition)
       意義:無論真假,至少執行一次循環體
       示例:
       awk 'BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}’
      
       for循環
       語法:for(expr1;expr2;expr3) {statement;…}
       常見用法:
       for(variable assignment;condition;iteration process)
       {for-body}
      

       特殊用法:能夠遍歷數組中的元素
       語法:for(var in array) {for-body}
       示例:
       awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
      
       性能比較
       time (awk 'BEGIN{ total=0;for(i=0;i<=10000;i++){total+=i;};print total;}')
       time(total=0;for i in {1..10000};do total=$(($total+i));done;echo $total)
       time(for ((i=0;i<=10000;i++));do let total+=i;done;echo $total)
       time(seq –s ”+” 10000|bc)
      
       switch語句
       語法:switch(expression) {case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2; ...; default: statementn}
       break和continue
       awk ‘BEGIN{sum=0;for(i=1;i<=100;i++)
       {if(i%2==0)continue;sum+=i}print sum}'
       awk ‘BEGIN{sum=0;for(i=1;i<=100;i++)
       {if(i==66)break;sum+=i}print sum}'
      
       break [n]
       continue [n]
       next:
      
      提前結束對本行處理而直接進入下一行處理(awk自身循環)
       awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd

      awk數組 關聯數組:array[index-expression] index-expression:

       (1) 可使用任意字符串;字符串要使用雙引號括起來
       (2) 如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為“空串”
       (3) 若要判斷數組中是否存在某元素,要使用“index in array”格式進行遍歷
       示例:
       weekdays["mon"]="Monday"
       awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";
       print weekdays["mon"]}‘
       awk '!line[$0]++' dupfile
       awk '{!line[$0]++;print $0, line[$0]}' dupfile
      
       若要遍歷數組中的每個元素,要使用for循環
       for(var in array) {for-body}
       注意:var會遍歷array的每個索引
       示例: awk‘BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday"; for(i in weekdays) {print weekdays[i]}}'
       netstat -tan | awk '/^tcp/{state[$NF]++}
       END{for(i in state) { print i,state[i]}}'
       awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
      
       數值處理:
       rand():返回0和1之間一個隨機數
       awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'
       字符串處理:
       length([s]):返回指定字符串的長度
       sub(r,s,[t]):對t字符串搜索r表示模式匹配的內容,并將第一個匹配內容替換為s
       echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
       echo "2008:08:08 08:08:08" | awk '{sub(/:/,"-",$1);print $0}'
       ?gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并全部替換為s所表示的內容
       echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
       echo "2008:08:08 08:08:08" | awk '{gsub(/:/,"-",$0);print $0}'
       ?split(s,array,[r]):以r為分隔符,切割字符串s,并將切割后的結果保存至array所表示的數組中,第一個索引值為1,第二個索引值為2,…
       netstat -tn | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}
       END{for (i in count) {print i,count[i]}}’
      
       數值處理:
       rand():返回0和1之間一個隨機數
       awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'
       ?字符串處理:
       ?length([s]):返回指定字符串的長度
       ?sub(r,s,[t]):對t字符串搜索r表示模式匹配的內容,并將第一個匹配內容替換為s
       echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
       echo "2008:08:08 08:08:08" | awk '{sub(/:/,"-",$1);print $0}'
       ?gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并全部替換為s所表示的內容
       echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
       echo "2008:08:08 08:08:08" | awk '{gsub(/:/,"-",$0);print $0}'
       ?split(s,array,[r]):以r為分隔符,切割字符串s,并將切割后的結果保存至array所表示的數組中,第一個索引值為1,第二個索引值為2,…
       netstat -tn | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}
       END{for (i in count) {print i,count[i]}}’
      

      awk函數 自定義函數格式:

       function name ( parameter, parameter, ... ) {
       statements
       return expression
       }
       示例:
       cat fun.awk
       function max(x,y) {
       x>y?var=x:var=y
       return var
       }
       BEGIN{a=3;b=2;print max(a,b)}
       awk -f fun.awk
      
       awk中調用shell命令
       system命令
       空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用空格分隔,或者說除了awk的變量外其他一律用""引用起來
       awk 'BEGIN{system("hostname") }'
       awk 'BEGIN{score=100; system("echo your score is " score) }'

      awk腳本

      將awk程序寫成腳本,直接調用或執行 示例:
      
       cat f1.awk
       {if($3>=1000)print $1,$3}
       awk -F: -f f1.awk /etc/passwd
       cat f2.awk
       #!/bin/awk –f
       #this is a awk script
       {if($3>=1000)print $1,$3}
       chmod +x f2.awk
       f2.awk –F: /etc/passwd
      
       向awk腳本傳遞參數
       格式:
       awkfile var=value var2=value2... Inputfile
       注意:在BEGIN過程中不可用。直到首行輸入完成以后,變量才可用。可以通過-v 參數,讓awk在執行BEGIN之前得到變量的值。命令行中每一個指定的變量都需要一個-v參數
       示例:
       cat test.awk
       #!/bin/awk –f
       {if($3 >=min && $3<=max)print $1,$3}
       chmod +x test.awk
       test.awk -F: min=100 max=200 /etc/passwd
      

       

      awk補充

      awk [options] -f progfile [var=value] file ...
       awk [options] [var=value] 'program' file ...
       POSIX options:  GNU long options: (standard)
           -f progfile --file=progfile           從腳本文件中讀取awk命令
           -F fs       --field-separator=fs      指定分隔符,fs是一個字符串或正則表達式
           -v var=val  --assign=var=val          賦值一個自定義變量
       Short options:  GNU long options: (extensions)
           -b          --characters-as-bytes     將所有輸入數據視為單字節字符(--posix覆蓋這個選項)
           -c          --traditional             在兼容模式下運行,awk=gawk
           -d[file]    --dump-variables[=file]   打印已排序的全局變量列表,沒有 file 打印幫助
           -e 'program-text'   --source='program-text'  使用 program-text 作為AWK程序源代碼
           -g          --gen-pot                 掃描并解析AWK程序,生成一個GNU.pot
           可移植對象模板)格式的文件
           -n          --non-decimal-data        識別輸入數據中的八進制和十六進制值
           -r          --re-interval             在正則表達式匹配中啟用間隔表達式的使用 
      
       awk內置變量:
       $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)
      
       = += -= *= /= %= ^= **=    賦值
       ?:                         C條件表達式
       ||                         邏輯或
       &&                         邏輯與
       ~ 和 !~                    匹配正則表達式和不匹配正則表達式
       < <= > >= != ==            關系運算符
       空格                        連接
       + -                        加,減
       * / %                      乘,除與求余
       + - !                      一元加,減和邏輯非
       ^                          求冪
       ++ --                      增加或減少,作為前綴或后綴
       $                          字段引用
       in                         數組成員
      
       條件語句
       if (expression) {
           statement;
           statement;
           ... ...
       }
       ?
       if (expression) {
           statement;
       } else {
           statement2;
       }
       ?
       if (expression) {
           statement1;
       } else if (expression1) {
       statement2;
       } else {
           statement3;
       }
       循環語句
       C語言:while、do/while、for、break、continue
      
       Examples:
       一.命令行方式調用awk
       awk [-F  field-separator]  'commands'  input-file(s)
       1 搜索/etc/passwd有root關鍵字的所有行
       awk -F: '/root/' /etc/passwd
       2 搜索/etc/passwd有root關鍵字的所有行,并顯示對應的shell
       awk -F: '/root/{print $7}' /etc/passwd
       3 打印/etc/passwd 中以:為分隔符分割的每行第一項
       awk -F: '{ print $1 }' /etc/passwd
       4 使用","分割,-F相當于內置變量FS, 指定分隔符
       awk -F, '{print $1,$2}' filename
       awk 'BEGIN{FS=","} {print $1,$2}' filename
       5 使用多個分隔符:先使用空格分割,然后對分割結果再使用","分割
       awk -F '[ ,]' '{print $1,$2,$5}' filename
       6 統計 file 行數
       awk '{ sum += $1 }; END { print sum }' file
       7 統計用戶個數
       awk '{count++;print $0;} END{print "user count is ",count}' /etc/passwd  
       8 行匹配語句 awk '' 只能用單引號
       awk '{[pattern] action}' {filenames}
       9 每行輸出文本中的1、4項,按空格或TAB分割
       awk '{print $1,$4}' filename
       10 格式化每行輸出文本中的1、4項,按空格或TAB分割
       awk '{printf "%-8s %-10s\n",$1,$4}' filename   
       11 設置變量a=1,b=s,每行輸出文本中的1項、1項+a(數字求和,非數字直接是a)、1項添加后綴b,按空格或TAB分割
       awk -va=1 -vb=s '{print $1,$1+a,$1b}' filename 
       12 查看filename文件內第20到第30行的所有內容
       awk '{if(NR>=20 && NR<=30) print $0}' filename 
       13 統計當前目錄下文件總大小,以M為單位輸出
       ll |awk 'BEGIN{size=0;} {size=size+$5;} END{print "[end]size is ",size/1024/1024,"M"}'  
       14 顯示/etc/passwd的賬戶,for循環遍歷數組
       awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
       15 按降序排序,篩選第二行小于70,統計總數(行數)
       sort -rnk2 1.txt|awk '$2<70'|wc-l
       二.shell腳本方式
       #!/bin/awk -f
       BEGIN{ 這里面放的是執行前的語句 }
       {這里面放的是處理每一行時要執行的語句}
       END {這里面放的是處理完所有的行后要執行的語句 }
       三.將所有的awk命令插入一個單獨文件,然后調用
       awk -f awk-script-file input-file(s)
      

      gsub函數的用法

       sub匹配第一次出現的符合模式的字符串,相當于 sed 's//'   
       gsub匹配所有的符合模式的字符串,相當于 sed 's//g'  
       例如:
       awk '{sub(/Mac/,"Macintosh");print}' urfile    用Macintosh替換Mac
       awk '{sub(/Mac/,"MacIntosh",$1); print}' file    第一個域內用Macintosh替換Mac
       把上面sub換成gsub就表示在滿足條件得域里面替換所有的字符。
       awk的sub函數用法:
       sub函數匹配指定域/記錄中最大、最靠左邊的子字符串的正則表達式,并用替換字符串替換這些字符串。
       如果沒有指定目標字符串就默認使用整個記錄。替換只發生在第一次匹配的時候。格式如下:
       sub (regular expression, substitution string):
       sub (regular expression, substitution string, target string)
      
       實例:
       $ awk '{ sub(/test/, "mytest"); print }' testfile
       $ awk '{ sub(/test/, "mytest", $1); print }' testfile
       第一個例子在整個記錄中匹配,替換只發生在第一次匹配發生的時候。
       第二個例子在整個記錄的第一個域中進行匹配,替換只發生在第一次匹配發生的時候。
      
       如要在整個文件中進行匹配需要用到gsub
       gsub函數作用如sub,但它在整個文檔中進行匹配。格式如下:
      gsub (regular expression, substitution string)
       gsub (regular expression, substitution string, target string)
      
       實例:
       $ awk '{ gsub(/test/, "mytest"); print }' testfile
       $ awk '{ gsub(/test/, "mytest", $1); print }' testfile
             第一個例子在整個文檔中匹配test,匹配的都被替換成mytest。
             第二個例子在整個文檔的第一個域中匹配,所有匹配的都被替換成mytest。
       另外, 只有當記錄中的域有改變的時候 ,指定0FS變量才有用, 如果記錄中的域無變化, 指定OFS產生不了實際效果。
      ?
       awk -F'|' -v OFS='|' '{ gsub(/[0-9]/, "", $3); print $0; }' data.txt   
       ?將把第三個域中所有數字都去掉。
       ?
      另外,對于數字的匹配,可以使用十六進制。?
      ?
       awk -F'|' -v OFS='|' '{ gsub(/[/x30-/x39]/, "", $3); print $0; }' data.txt 
      

      基本正則表達式 BRE 元字符

       字符匹配:
       .            匹配任意單個字符
       []           匹配指定范圍內的任意單個字符,示例:[wang] [0-9] [a-z] [a-zA-Z]
       [^]          匹配指定范圍外的任意單個字符
       匹配次數:
       用在要指定次數的字符后面,用于指定前面的字符要出現的次數
       *         匹配前面的字符任意次,包括0次,貪婪模式:盡可能長的匹配
        .*        任意長度的任意字符
        \?        匹配其前面的字符0或1次
        \+        匹配其前面的字符至少1次
        \{n\}     匹配前面的字符n次
        \{m,n\}   匹配前面的字符至少m次,至多n次
        \{,n\}    匹配前面的字符至多n次
       \{n,\}    匹配前面的字符至少n次
       匹配次數:
       用在要指定次數的字符后面,用于指定前面的字符要出現的次數
        *         匹配前面的字符任意次,包括0次,貪婪模式:盡可能長的匹配
        .*        任意長度的任意字符
        \?        匹配其前面的字符0或1次
        \+        匹配其前面的字符至少1次
        \{n\}     匹配前面的字符n次
        \{m,n\}   匹配前面的字符至少m次,至多n次
        \{,n\}    匹配前面的字符至多n次
        \{n,\}    匹配前面的字符至少n次
       -  位置錨定:
       定位出現的位置
       ^               行首錨定,用于模式的最左側
       $               行尾錨定,用于模式的最右側
       ^PATTERN$       用于模式匹配整行
       ^$              空行
       ^[[:space:]]*$  空白行
       \< 或 \b        詞首錨定,用于單詞模式的左側
       \> 或 \b        詞尾錨定,用于單詞模式的右側
       \<PATTERN\>     匹配整個單詞
       \w              某個單詞
       分組:\(\) 
       將一個或多個字符捆綁在一起,當作一個整體處理,如:\(root\)\+
       分組括號中的模式匹配到的內容,會被正則表達式引擎記錄于內部的變量中,
       這些變量的命名方式為: \1, \2, \3, ...
       示例:
       \(string1\(string2\)\)
       \1 :string1\(string2\)  # 表示從左側起第一個左括號以及與之匹配右括號之間的模式所匹配到的字符。
       \2 :string2
       后向引用:引用前面的分組括號中的模式所匹配字符,而非模式本身
       ?
       或:\|
       示例:a\|b        a或b
            C\|cat      C或cat
            \(C\|c\)at  Cat或ca
       字符匹配:
       .   任意單個字符
       []  指定范圍的字符
       [^] 不在指定范圍的字符
       次數匹配:
       *     匹配前面字符任意次
       ?     0或1次
       +     1次或多次
       {m}   匹配m次
       {m,n} 至少m,至多n次
       *     匹配前面字符任意次
       ?     0或1次
       +     1次或多次
       {m}   匹配m次
       {m,n} 至少m,至多n次
       位置錨定:
       ^      行首
       $      行尾
       \<, \b 語首
       \>, \b 語尾
       \w     單詞
       分組:()
       ?
       后向引用:\1, \2, ...
       ?
       或:
       a|b      a或b
       C|cat    C或cat
       (C|c)at  Cat或cat
       特殊字符集
       字符集需要用 [ ] 來包含住,否則不會生效
       [:alnum:]    字母和數字
       [:alpha:]    代表任何英文大小寫字符,亦即 A-Z, a-z
       [:lower:]    小寫字母 
       [:upper:]    大寫字母
       [:blank:]    空白字符(空格和制表符)
       [:space:]    水平和垂直的空白字符(比[:blank:]包含的范圍廣)
       [:cntrl:]    不可打印的控制字符(退格、刪除、警鈴...)
       [:digit:]    十進制數字 
       [:xdigit:]   十六進制數字
       [:graph:]    可打印的非空白字符
       [:print:]    可打印字符
       [:punct:]    標點符號
       *                 匹配任意零個或多個字符
       ?                 匹配任意一個字符
       [0-9]             匹配任意數字
       [a-z]             匹配任意小寫字母
       [A-Z]             匹配任意大寫字母
       []                匹配中括號里任意一個字符,- 指定范圍
       [^] ; [!]         匹配中括號里任意字符以外的字符,取反
       大括號擴展
       &>>file    把 標準輸出 和 標準錯誤 都追加重定向到file
      

      練習題:

      1、文件ip_list.txt如下格式,請提取”.magedu.com”前面的主機名部分并寫入到回到該文件中 1 blog.magedu.com 2 www.magedu.com 999 study.magedu.com

       [root.CentOS 7] ~ awk -F. '{print $1}' ip-list.txt >> ip-list.txt
      

      2、統計/etc/fstab文件中每個文件系統類型出現的次數

       [root.CentOS 7] ? awk '/^[^#].*$/{print $3}' /etc/fstab |sort|uniq -c
      

      3、統計/etc/fstab文件中每個單詞出現的次數

       [root.CentOS 7] ? awk 'gsub(/[^[:alpha:]]/,"\n",$0)' /etc/fstab | sort|uniq -c
      

      4、提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中的所有數字

       [root.CentOS 7] ? echo "Yd$C@M05MB%9&Bdh7dq+YVixp3vpw" | awk 'gsub(/[^[:digit:]]/,"",$0)'
      

      5、有一文件記錄了1-100000之間隨機的整數共5000個,存儲的格式100,50,35,89…請取出其中最大和最小的整數

       awk -F, '{if($1>$2){big=$1;small=$2}\
       else{big=$2;small=$1}\
       for(i=3;i<=NF;i++){\
       if(big<$i){big=$i}\
       if(small>$i){small=$i}\
       }}\
       END{print "big:"big"\nsmall:"small}' RANDOM.txt
      

      6、解決DOS攻擊生產案例:根據web日志或者或者網絡連接數,監控當某個IP并發連接數或者短時內PV達到100,即調用防火墻命令封掉對應的IP,監控頻率每隔5分鐘。防火墻命令為:iptables -A INPUT -s IP -j REJECT

       >crontab -e
       */5 * * * * bash dos.sh
       >cat dos.sh
       #!/bin/bash
       ss -t | awk -F "[[:space:]]+|:" '{count[$6]++;}END{for(i in count){if(count[i]>1){system("iptables  -A INPUT -s " i " -j REJECT")}}}'
      

      7、將以下文件內容中FQDN取出并根據其進行計數從高到低排序

      http://mail.magedu.com/index.html
      http://www.magedu.com/test.html
      http://study.magedu.com/index.html
      http://blog.magedu.com/index.html
      http://www.magedu.com/images/logo.jpg
      http://blog.magedu.com/20080102.html
      [root.CentOS 7] ? awk -F "[/|.]" '{count[$3]++}END{for(i in count){print i,count[i]}}' url.txt
      

      8、將以下文本以inode為標記,對inode相同的counts進行累加,并且統計出同一inode中,beginnumber的最小值和endnumber的最大值

       inode|beginnumber|endnumber|counts| 106|3363120000|3363129999|10000| 106|3368560000|3368579999|20000| 
      310|3337000000|3337000100|101| 310|3342950000|3342959999|10000| 310|3362120960|3362120961|2|
      311|3313460102|3313469999|9898| 311|3313470000|3313499999|30000| 311|3362120962|3362120963|2|
      輸出的結果格式為: 310|3337000000|3362120961|10103| 311|3313460102|3362120963|39900| 106|3363120000|3368579999|30000| awk -F "|" -v OFS="|" 'NR==1{print $0}\ NR>1{count[$1]+=$4;if(max[$1]<$3){max[$1]=$3}\ if(!min[$1]){min[$1]=$2}if(min[$i]>$2){min[$1]=$2}}\ END{for(i in count){print i,min[i],max[i],count[i]"|"}}' inode.txt

       

       





      posted @ 2021-03-01 21:48  上善若水~小輝  閱讀(195)  評論(0編輯  收藏
      最新chease0ldman老人|无码亚洲人妻下载|大香蕉在线看好吊妞视频这里有精品www|亚洲色情综合网

        <sub id="gqw76"><listing id="gqw76"></listing></sub>
        <sub id="gqw76"><listing id="gqw76"></listing></sub>

      1. <form id="gqw76"><legend id="gqw76"></legend></form>