天天看點

Linux基礎學習筆記4-文本處理

本章内容

Linux基礎學習筆記4-文本處理

抽取文本的工具

檔案内容:less和cat
檔案截取:head和tail
按列抽取:cut
按關鍵字抽取:grep
           
檔案檢視
    檔案檢視指令:cat,tac,rev
    cat [OPTION] ...[FILE] ...
        -E:顯示行結束符$
        -n:對顯示的每一行進行編号
        -A:顯示所有控制符
        -b:非空行編号
        -s:壓縮連續的空行成一行
    tac,rev:倒着輸出顯示
           
Linux基礎學習筆記4-文本處理

分頁檢視檔案内容

more:分頁檢視檔案内容
    more [OPTIONS...] FILE...
        -d:顯示翻頁及退出提示
less:一頁一頁地檢視檔案或STDIN輸出
    檢視時有用的指令包括:    /文本    搜尋文本
                                        n/N    跳到下一個或上一個比對
less 指令是man指令使用的分頁器
           
顯示文本前或後幾行内容
           
head [OPTION] ...[FILE]...
  -c #:指定擷取前#位元組
  -n #:指定擷取前#行
  -#:指定行數
tail [OPTION]...[FILE]...
  -c #:指定擷取後#位元組
  -n #:指定擷取後#行
  -f:跟蹤顯示檔案fd新追加的内容,常用日志監控
    相當于 --follow=descriptor
  -F:跟蹤檔案名,相當于--follow=name --retry
tailf 類似于tail -f,當檔案不增長時并不通路檔案
           

按列抽取文本cut和合并檔案paste

cut [OPTION]...[FILE]...
    -d DELIMINTER:指明分隔符,預設tab
  -f FILEDS:
    #:第#個字段
    #,#,[,#]:離散的多個字段,例如1,3,6
    #-#:連續的多個字段,例如1-6
  混合使用:1-3,7
  -c 按字元切割
  --output-delimiter=STRING指定輸出分隔符

顯示檔案或STDIN資料的指定列
  示例:cut -d: -f1 /etc/passwd
     cat /etc/passwd | cut -d: -f7
    cut -c2-5 /usr/share/dict/words
paste合并兩個檔案同行号的列到一行
  paste [OPTION]...[FILE]...
  -d 分隔符:指定分隔符,預設用TAB
  -s:所有行合并成一行顯示
  paste f1 f2
  paste -s f1 f2
  paste用法:http://www.runoob.com/linux/linux-comm-paste.html      

sort指令:用于将文本檔案内容加以排序.  http://www.runoob.com/linux/linux-comm-sort.html

uniq指令:用于檢查及删除文本檔案中重複出現的行列,一般與 sort 指令結合使用.  http://www.runoob.com/linux/linux-comm-uniq.html

wc(word count)指令:用于計算字數 http://www.runoob.com/linux/linux-comm-wc.html

df指令:用于顯示目前在Linux系統上的檔案系統的磁盤使用情況統計。http://www.runoob.com/linux/linux-comm-df.html

Linux文本處理三劍客

grep:文本過濾(模式:pattern)工具
    grep,eprep,fgrep(不支援正規表達式搜尋)
sed:stream editor,文本編輯工具
awk:Linux上實作gawk,文本報告生成器
           

grep

grep:Global search REgular expression and Print out the line
    作用:文本搜尋工具,根據使用者指定的"模式"對文本逐行進行比對檢查;列印比對到的行
    模式:由正規表達式字元及文本字元所編寫的過濾條件。
grep [OPTIONS] PATTERN [FILE...]
    grep root /etc/passwd
    grep "$USER" /ect/passwd
    grep '$USER' /etc/passwd
    grep `whoami` /ect/passwd

grep指令選項
    --color=auto:對比對到的文本着色顯示
    -v:顯示不被pattern比對到的行
    -i:忽略字元大小寫
    -n:顯示比對的行号
    -o:僅顯示比對到的字元串
    -c:統計比對的行數
    -q:靜默模式,不輸出任何資訊  ####配合echo $?指令使用,該指令可用來判斷上一個億指令是否成功,成功輸出0,否則非0.
    -A #:after,顯示後#行
    -B #:before,顯示前#行
    -C #:context,前後各#行
    -e:實作多個選項間的邏輯or關系
        grep -e 'cat' -e 'dog' file
    -w:比對整個單詞
    -E:使用ERE
    -F:相當于fgrep,不支援正規表達式
           

正規表達式

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

基本正規表達式字元
字元比對:
  . 比對任意單個字元
  [] 比對指定範圍内的任意單個字元
  [^] 比對指定範圍外的任意單個字元
  [:alnum:] 字母和數字
  [:alpha:] 代表任何英文大小寫字元,亦即A-Z,a-z
         
比對次數:用在要指定次數的字元後面,用于指定前面的字元要出現的次數      
* 比對前面的字元任意次,包括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      

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      

 Vim簡介 http://www.runoob.com/linux/linux-vim.html

vi:Visual Interface,文本編輯器
文本:ASCII,Unicode
文本編輯種類:
    行編輯器:sed
    全屏編輯器:nano,vi
    vim - Vi Improved
其他編輯器:
    gedit 一個簡單的圖形編輯器
    gvim 一個Vim編輯器的圖形版本

打開檔案
#vim [OPTION]... FILE...
    +#:打開檔案後,讓光标處于第#行的行首,+預設行尾
    +/PATTERN:打開檔案後,直接讓光标處于第一個被PATTERN比對到的行的行首
    -b file 二進制方式打開檔案
    -d file1 file2... 比較多個檔案
    -m file 隻讀打開檔案
ex file 或vim -e 直接進入ex模式
如果該檔案存在,檔案被打開并顯示内容
如果該檔案不存在,當編輯後第一次存盤時建立它

vim:一個模式編輯器
擊鍵行為是依賴于vim的"模式"
三種主要模式:
    指令(Normal)模式:預設模式,移動光标,剪切/粘貼文本
    插入(Insert)或編輯模式:修改文本
    擴充指令(extended command)模式(即底線指令模式):儲存,退出等
Esc鍵:退出目前模式
Esc鍵+Esc鍵:總是傳回到指令模式
           
Linux基礎學習筆記4-文本處理

模式轉換:

指令模式-->輸入模式(插入模式):
  i :insert,在光标所在處輸入
  I:在目前光标所在行的行首輸入
  a:append,在光标所在處後面輸入
  A:在目前光标所在行的行尾輸入
  o:在目前光标所在行的下方打開一個新行
  O:在目前光标所在行的上方打開一個新行
輸入模式-->指令模式:
  Esc鍵
指令模式-->底線指令模式(擴充指令模式)
  :
底線指令模式-->指令模式
  Esc鍵,Enter鍵      

 關閉檔案

擴充模式:
    :q     退出
    :q!  強制退出,丢棄做出的修改
    :wq   儲存退出
    :x     儲存退出

按":"進入擴充指令模式
建立一個指令提示符:處于底部的螢幕左側
指令:
  w  寫磁盤檔案
  wq  寫入并退出
  x  寫入并退出
  q  退出
  q! 不存盤退出,即使更改都将丢失
  r filename  讀檔案内容到目前檔案中
  w filename  将目前檔案内容寫入另一個檔案
  !command   執行指令
  r!command  讀入指令的輸出
  

指令模式
    ZZ:儲存退出
    ZQ:不儲存退出

指令模式光标跳轉
字元間跳轉:
  h:左 l:右 j:下 k:上
  #COMMAND:跳轉由#指定的個數的字元
單詞間的跳轉:
  w:下一個單詞的詞首
  e:下一個單詞的詞尾
  b:目前或前一個單詞的詞首
  #COMMAND:由#指定一次跳轉的單詞數
目前頁跳轉:
  H:頁首  
  M:頁中間行
  L:頁底
行首行尾跳轉:
  ^:跳轉至行首的第一個非空白字元
  0:跳轉至行首
  $:跳轉至行尾
行間移動:
  #G、擴充模式:#:跳轉至由#指定行
  G:最後一行
  1G,gg:第一行
句間移動:
  ):下一句  (:上一句
段落間移動:
  }:下一段  {:上一段

指令模式操作:
  x:删除光标處的字元
  #x:删除光标處起始的#個字元
  xp:交換光标所在處的字元及其後面的字元的位置
  ~:轉換大小寫
  J:删除目前行後的換行符
替換指令(r,replace)
  r:替換光标所在處的字元
  R:切換成REPLACE模式
删除指令:
  d:删除指令,可結合光标跳轉字元,實作範圍删除
  d$:删除到行尾
  d^:删除到非空行首
  d0:删除到行首
  dw:删除一個單詞
  #COMMAND
dd:删除光标所在的行
  #dd:多行删除
D:從目前光标位置一直删除到行尾,留白行,等同于d$

複制指令(y,yank)
  y:複制,行為類似于d指令
  y$,y0,y^等
  yy:複制行
    #yy:複制多行
  Y:複制整行
粘貼指令(p,paste)
  p:緩沖區存的如果為整行,則粘貼目前光标所在行的下方;否則,則粘貼至目前光标所在處的後面
  P:緩沖區存的如果為整行,則粘貼目前光标所在行的上方;否則,則粘貼至目前光标所在處的前面
改變指令(c,change):
  c:修改後切換成插入模式
指令模式-->插入模式
  c$
  c^
  c0
cc:删除目前行并輸入新内容,相當于S
  #cc:
C:删除目前光标到行尾,并切換成插入模式

擴充指令模式:位址界定
位址界定
  :start_pos,end_pos
  # 具體第#行,例如2表示第2行
  #,# 從左側#表示的起始行,加上右側#表示的行數  示例::2,+3 表示2到5行
  . 目前行
  $ 最後一行  示例: .,$-1 目前行到倒數第二行
  % 全文,相當于1,$

/pattern1/,/pattern2/
  從第一次被part1模式比對到的行開始,一直到第一次被part2比對到的行結束
  #,/pattern/
  /pattern/,$
使用方式:後跟一個編輯指令
  d  删除
  y  拷貝
  w file:将範圍内的行另存至指定檔案中
  r file:在指定位置插入指定檔案中的所有内容
  示例: :1,/^f/d 從第一行開始删除到不以f開頭的行

擴充指令模式:查找
查找
  /PATTERN:從目前光标所在處從檔案尾部查找
  ?PATTERN:從目前光标所在處向檔案首部查找
  n:與指令同方向
  N:與指令反方向
查找并替換
s:在擴充模式下完成替換操作
  格式:s/要查找的内容/替換為的内容/修飾符
  要查找的内容:可使用模式
  替換為的内容:不能使用模式,但可以使用\1,\2,...等向後引用符号;還可以使用"&"引用前面查找時查找到的整個内容
  修飾符:
    i:忽略大小寫
    g:全局替換;預設情況下,每一行隻替換第一次出現  
    gc:全局替換,每次替換前詢問
查找替換中的分隔符/可替換為其他字元,例如
  [email protected]/[email protected]/var/@g
  s#/boot#/#i

指令模式:撤銷更改
  u撤銷最近的更改
  #u撤銷之前多次更改
  U 撤銷光标落在這行後所有此行的更改
  按Ctrl -r重做最後的"撤銷"更改
  .重複前一個操作
  n.重複前一個操作n次

可視化模式(類似光标的選擇效果)
允許選擇的文本塊  
  v 面向字元
  V 面向行
  ctrl -v 面向塊
可視化鍵可用于與移動鍵結合使用
  w ) } 箭頭等
突出顯示的文字可被删除、複制、變更、過濾、搜尋、替換等

使用多個"視窗"
多檔案分割
  vim -o|-O FILE1 FILE2 ...
  -o:水準分割
  -O:垂直分割
  在視窗切換:Ctrl+w,方向鍵
單檔案分割
  Ctrl+w,s:split,上下分割
  Ctrl+w,v:vertical,垂直分割
  ctrl+w,q:取消相鄰視窗
  ctrl+w,o:取消全部視窗
  :wqall 退出      

定制vim的工作特性

配置檔案:永久有效
    全局:/etc/vimrc
    個人:~/.vimrc
擴充模式:目前vim程序有效
1)行号 
    顯示:set number,簡寫為set nu
    取消顯示:set nonumber,簡寫為set nonu
2)忽略字元的大小寫
    啟用:set ic
    不忽略:set noic
3)自動縮進
    啟用:set ai
    禁用:set noai
4)智能縮進
    啟用:smartindent 簡寫 set is
    禁用:set nois
5)高亮搜尋
    啟用:set hlsearch
    禁用:set nohlsearch
6)文法高亮
    啟用:syntax on
    禁用:suntax off
7)顯示Tab和換行符^I和$顯示
    啟用:set list
    禁用:set nolist
8)檔案格式
    啟用windows格式:set fileformat=dos
    啟用unix格式:set fileformat=unix
    簡寫:set ff=dos|unix  
           

處理文本的工具sed 

Stream EDitor,行編輯器
sed是一種流編輯器,它一次處理一行内容。處理時,把目前處理的行存儲在臨時緩沖區中,稱為“模式空間”,接着用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)位址範圍:
      #,#
      #,+#
      /pattern1/,/pattern2/
      #,/pattern1/
  (4)~:步進
      1~2 奇數行
      2~2 偶數行
  
編輯指令:
  d:删除模式空間比對的行,并立即啟用下一輪循環
  p:列印目前模式空間的内容,追加到預設輸出之後
  a [\]text:在指定行後面追加文本(支援使用\n實作追加多行)
  i [\]text:在行前面插入文本
  c [\]text:替換行為為單行或多行文本
  w /path/somefile:儲存模式比對的行至指定檔案
  r /path/somefile:讀取指定檔案的文本至模式空間中,比對到的行後
  =:為模式空間中的行列印行号
  !:模式空間中比對行取反處理
  s///:查找替換,支援使用其他分隔符,[email protected]@@,s###
  替換标記:
    g:行内全局替換
    p:顯示替換成功的行
    w /PATH/TO/SOMEFILE:将替換成功的行儲存至檔案中 
sed示例:
  sed '2p' /ect/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
  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指令:nl(Number of Lines)将指定的檔案添加行号标注後寫到标準輸出
  nl /etc/passwd | sed '2,5d'
  nl /etc/passwd | sed '2a tea'
  sed 's/test/mytest/g' file
  sed -n 's/root/&superman/p' /etc/passwd 單詞前
  sed -n 's/root/superman&/p' /etc/passwd 單詞後
  sed -e 's/dog/cat/' -e 's/hi/ih/' pets
  sed -i.bak 's/dog/cat/g' pets      
工作模式:模式空間和保持空間介紹
模式空間:初始化為空,處理完一行後會自動輸出到螢幕并清除模式空間。
保持空間:初始化為一個空行,也就是預設帶一個\n,處理完後不會自動清除。 模式空間:可以想成工程裡面的流水線,資料之間在它上面進行處理,用于處理文本行。 
保持空間:可以想象成倉庫,我們在進行資料處理的時候, 作為資料的暫存區域,用于保留文本行,是儲存已經處理過的 輸入行,預設有一個空行。
https://www.cnblogs.com/276815076/p/7879666.html
      
P:列印模式空間開端至\n内容,并追加到預設輸出之前
h:把模式空間中的内容覆寫至保持空間中
H:把模式空間中的内容追加至保持空間中
g:從保持空間取出資料覆寫至模式空間
G:從保持空間追加至模式空間
x:把模式空間中的内容與保持空間中的内容進行互換
n:讀取比對到的行的下一行覆寫至模式空間
N:讀取比對到的行的下一行追加至模式空間
d:删除模式空間中的行
D:如果模式空間包含換行符,則删除直到第一個換行符的模式空間中的文本,并不會讀取新的輸入行,而使用合成的模式空間重新啟動循環。如果模式空間不包含換行符,則會發出d指令那樣啟動正常的新循環。      

進階編輯指令sed示例: 

sed -n 'n;p' FILE
sed '1!G;h;$!d' FILE
sed 'N;D' FILE
sed '$!N;$!D' FILE
sed '$!d' FILE
sed 'G' FILE
sed 'g' FILE
sed '/^$/d;G' FILE
sed 'n;d' FILE
sed -n '1!G;h;$p' FILE 
           

awk介紹

awk:Aho,Weinberger,Kernighan,報告生成器,格式化文本輸出
有多種版本:New awk(nawk),HNU awk(gawk)
gawk:模式掃描和處理語言
基本用法:
    awk [option] 'program' var=value file...
    awk [option] -f programfile var=value file...
    awk [options] 'BEGIN'{action;...} pattern{action;...} END{action;...}' file...
    awk程式通常由:BEGIN語句塊、能夠使用模式比對的通用語句塊、END語句塊,共3部分組成
    program通常是被放在單引号或雙引号中
    選項:
        -F 指明輸入時用到的字段分隔符
        -v var=value:自定義變量
基本格式: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;...}語句塊
BAGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變量初始化、列印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中
END語句塊在awk從輸入流中讀取完所有行之後即被執行,比如列印所有行的分析結果這類資訊彙總都是在END語句塊中完成,它也是一個可選語句塊
pattern語句塊中的通用指令是最重要的部分,也是可選的。如果沒有提供pattern語句塊,則預設執行print,即列印每一個讀取到的行,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 $1"\t"$3}' /etc/passwd
  tail -3 /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/passwd 引用内置變量不用$
  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 /etc/passwd

printf指令
格式化輸出:printf "FORMAT",item1,item2,...
  (1)必須指定FORMAT
  (2)不會自動換行,需要顯示給出換行控制符
  (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,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
函數調用:function_name(argu1,argu2,...)
條件表達式(三目表達式):
  selector?if-true-expression:if-false-expression
示例:
  awk -F: '{$3>=1000?usertype="CommonUser":usertype="SystemUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
awk PATTERN
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: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
  awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd
(4)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
(5)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;print i}'
  seq 10 | awk '!(i=!i)'
  seq 10 | awk -v i=1 'i=!i'

awk action
常用的action分類
  (1)Expression:算術,比較表達式等
  (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(condition){statements;...}
  do{statements;...}while(condition)
  for(expr1;expr2;expr3){statements;...}
  break
  continue  
  delete array[index]
  delete array
  exit

awk控制語句if-else
文法:if(condition){statements;...}[else statements]
   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){print "Common user:%s\n",$1}else {printf "root or Ststem:%s\n",$1}}' /etc/passwd
  awk -F: '{if($3>=1000) printf "Common user:%s\n",$1;else printf "root or System:%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"}'

awk控制語句while
while循環
文法:while(condition){statement;...}
條件"真",進入循環;條件"假",退出循環
使用場景:
  對一行内的多個字段逐一類似處理時使用
  對數組中的各元素逐一處理時使用
示例:
  awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i);i++}}' /etc/hrub2.cfg
  awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){if(length($i)>=10){print $i,length($i)};i++}}' /etc/grub2.cfg
awk控制語句do-while
do-while循環
文法:do{statement;...}while(condition)
意義:無論條件真假,至少執行一次循環體
示例:
  awk 'BEGIN{total=0;i=0;do{total +=i;i++}while(i<=100);print total}'

awk控制語句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

awk控制語句 break [n]
       continue [n]
next:
  提前結束對本行處理而直接進入下一行處理(awk自身循環)
  示例:awk -F: '{if($3%2!=0) next;print $1,$3}' /etc/passwd

awk數組
若要周遊數組中的每個元素,要使用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

awk函數處理
數值處理:
  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)'
  gsub(r,s,[t]):對t字元串進行搜素r表示的模式比對的内容,并全部替換為s所表示的内容
    echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
  split(s,array,[r]):以r為分隔符,切割字元串s,并将切割後的結果儲存至array所表示的數組中,第一個索引值為1,第二個索引值為2,...
    netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++} END{for(i in count){print i,count[i]}}'      

轉載于:https://www.cnblogs.com/xiaoshayu520ly/p/10544200.html

繼續閱讀