Linux文本三劍客超詳細教程---grep、sed、awk

  awkgrepsedlinux操做文本的三大利器,合稱文本三劍客,也是必須掌握的linux命令之一。三者的功能都是處理文本,但側重點各不相同,其中屬awk功能最強大,但也最複雜。grep更適合單純的查找或匹配文本,sed更適合編輯匹配到的文本,awk更適合格式化文本,對文本進行較複雜格式處理。linux

一、grep

1.1 什麼是grepegrep

  Linux系統中grep命令是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來(匹配到的標紅)。grep全稱是Global Regular Expression Print,表示全局正則表達式版本,它的使用權限是全部用戶。git

  grep的工做方式是這樣的,它在一個或多個文件中搜索字符串模板。若是模板包括空格,則必須被引用,模板後的全部字符串被看做文件名。搜索的結果被送到標準輸出,不影響原文件內容。正則表達式

  grep可用於shell腳本,由於grep經過返回一個狀態值來講明搜索的狀態,若是模板搜索成功,則返回0,若是搜索不成功,則返回1,若是搜索的文件不存在,則返回2。咱們利用這些返回值就可進行一些自動化的文本處理工做。shell

  egrep = grep -E:擴展的正則表達式 (除了\< , \> , \b 使用其餘正則均可以去掉\數據庫

 

1.2 使用grep

1.2.1 命令格式

grep [option] pattern file

 

1.2.2 命令功能

用於過濾/搜索的特定字符。可以使用正則表達式能多種命令配合使用,使用上十分靈活。express

 

1.2.3 命令參數

經常使用參數已加粗編程

  •  -A<顯示行數>:除了顯示符合範本樣式的那一列以外,並顯示該行以後的內容。
  •  -B<顯示行數>:除了顯示符合樣式的那一行以外,並顯示該行以前的內容。
  •  -C<顯示行數>:除了顯示符合樣式的那一行以外,並顯示該行以前後的內容。
  •  -c:統計匹配的行數
  •  -e :實現多個選項間的邏輯or 關係
  •  -E:擴展的正則表達式
  •  -f FILE:從FILE獲取PATTERN匹配
  •  -F :至關於fgrep
  •  -i --ignore-case #忽略字符大小寫的差異。
  •  -n:顯示匹配的行號
  •  -o:僅顯示匹配到的字符串
  •  -q: 靜默模式,不輸出任何信息
  •  -s:不顯示錯誤信息。
  •  -v:顯示不被pattern 匹配到的行,至關於[^] 反向匹配
  •  -w :匹配 整個單詞

 

1.3 grep實戰演示

 

 二、正則表達式

2.1 認識正則

1)介紹數組

  正則表達式應用普遍,在絕大多數的編程語言均可以完美應用,在Linux中,也有着極大的用處。緩存

  使用正則表達式,能夠有效的篩選出須要的文本,而後結合相應的支持的工具或語言,完成任務需求。bash

  在本篇博客中,咱們使用grep/egrep來完成對正則表達式的調用

 

2)正則表達式類型

正則表達式可使用正則表達式引擎實現,正則表達式引擎是解釋正則表達式模式並使用這些模式匹配文本的基礎軟件。

Linux中,經常使用的正則表達式有:

  •  POSIX 基本正則表達式(BRE)引擎
  •  POSIX 擴展正則表達式(BRE)引擎

 

2.2 基本正則表達式

2.2.1 匹配字符

1)格式

  •  . 匹配任意單個字符,不能匹配空行
  •   [] 匹配指定範圍內的任意單個字符
  •   [^] 取反
  •   [:alnum:] [0-9a-zA-Z]
  •   [:alpha:] [a-zA-Z]
  •   [:upper:] [A-Z]
  •   [:lower:] [a-z]
  •   [:blank:] 空白字符(空格和製表符)
  •   [:space:] 水平和垂直的空白字符(比[:blank:]包含的範圍廣)
  •   [:cntrl:] 不可打印的控制字符(退格、刪除、警鈴...
  •   [:digit:] 十進制數字 或[0-9]
  •   [:xdigit:]十六進制數字
  •   [:graph:] 可打印的非空白字符
  •   [:print:] 可打印字符
  •   [:punct:] 標點符號

2)演示

 

2.2.2 配置次數

1)格式

  •  *  匹配前面的字符任意次,包括0,貪婪模式:儘量長的匹配
  •  .*  任意長度的任意字符,不包括0
  •  \?  匹配其前面的字符0 1
  •  \+  匹配其前面的字符至少1
  •  \{n\}  匹配前面的字符n
  •  \{m,n\}  匹配前面的字符至少m 次,至多n
  •  \{,n\}  匹配前面的字符至多n
  •  \{n,\}  匹配前面的字符至少n

2)演示

 

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

1)格式

  •  ^  行首錨定,用於模式的最左側
  •  $  行尾錨定,用於模式的最右側
  •  ^PATTERN$,用於模式匹配整行
  •  ^$ 空行
  •  ^[[:space:]].*$  空白行
  •  \< \b  詞首錨定,用於單詞模式的左側
  •  \> \b  詞尾錨定;用於單詞模式的右側
  •  \<PATTERN\>

2)演示

 

2.2.4 分組和後向引用

1)格式

分組:\(\) 將一個或多個字符捆綁在一塊兒,看成一個總體進行處理

  分組括號中的模式匹配到的內容會被正則表達式引擎記錄於內部的變量中,這些變量的命名方式爲: \1, \2, \3, ...

後向引用

引用前面的分組括號中的模式所匹配字符,而非模式自己

\1 表示從左側起第一個左括號以及與之匹配右括號之間的模式所匹配到的字符

\2 表示從左側起第2個左括號以及與之匹配右括號之間的模式所匹配到的字符,以此類推

\& 表示前面的分組中全部字符

③ 流程分析以下:

2)演示

 

2.3 擴展正則表達式

1)字符匹配:

  •  .  任意單個字符
  •  []  指定範圍的字符
  •  [^] 不在指定範圍的字符
  •    次數匹配:
  •  * :匹配前面字符任意次
  •  ?  : 0 1
  •  + 1 次或屢次
  •  {m} :匹配m次 次
  •  {m,n} :至少m ,至多n

2)位置錨定:

  •  ^ : 行首
  •  $ : 行尾
  •  \<, \b : 語首
  •  \>, \b : 語尾
  •    分組:()
  •  後向引用:\1, \2, ...

3)總結

  除了\<, \b : 語首、\>, \b : 語尾;使用其餘正則均可以去掉\;上面有演示案例,不在進行演示

 

三、sed

3.1 認識sed

  sed 是一種流編輯器,它一次處理內容。處理時,把當前處理的行存儲在臨時緩衝區中,稱爲模式空間patternspace ),接着用sed 命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕。而後讀入下行,執行下一個循環。若是沒有使諸如‘D’ 的特殊命令,那會在兩個循環之間清空模式空間,但不會清空保留空間。這樣不斷重複,直到文件末尾。文件內容並無改變,除非你使用重定向存儲輸出或-i

  功能:主要用來自動編輯一個或多個文件, 簡化對文件的反覆操做

 

3.2 使用sed

3.2.1 命令格式

sed [options] '[地址定界] command' file(s)

  

3.2.2 經常使用選項options

  •  -n:不輸出模式空間內容到屏幕,即不自動打印,只打印匹配到的行
  •  -e多點編輯,對每行處理時,能夠有多個Script
  •  -f:把Script寫到文件當中,在執行sed-f 指定文件路徑,若是是多個Script,換行寫
  •  -r:支持擴展的正則表達式
  •  -i:直接將處理的結果寫入文件
  •  -i.bak:在將處理的結果寫入文件以前備份一份

 

3.2.3 地址定界

  •  不給地址:對全文進行處理
  •  單地址:
    •  #: 指定的行
    •  /pattern/:被此處模式所可以匹配到的每一行
  •  地址範圍:
    •  #,#
    •  #,+#
    •  /pat1/,/pat2/
    •  #,/pat1/
  •  ~:步進
    •   sed -n '1~2p'  只打印奇數行 1~2 從第1行,一次加2行)
    •   sed -n '2~2p'  只打印偶數行

 

3.2.4 編輯命令command

  •  d:刪除模式空間匹配的行,並當即啓用下一輪循環
  •  p:打印當前模式空間內容,追加到默認輸出以後
  •  a:在指定行後面追加文本,支持使用\n實現多行追加
  •  i:在行前面插入文本,支持使用\n實現多行追加
  •  c替換行爲單行或多行文本,支持使用\n實現多行追加
  •  w:保存模式匹配的行至指定文件
  •  r:讀取指定文件的文本至模式空間中匹配到的行後
  •  =:爲模式空間中的行打印行號
  •  !:模式空間中匹配行取反處理
  •  s///查找替換,支持使用其它分隔符,如:s@@@s###
    •  g表示行內全局替換;
    •  在替換時,能夠加一下命令,實現大小寫轉換
    •  \l:把下個字符轉換成小寫。
    •  \L:把replacement字母轉換成小寫,直到\U\E出現。
    •  \u:把下個字符轉換成大寫。
    •  \U:把replacement字母轉換成大寫,直到\L\E出現。
    •  \E:中止以\L\U開始的大小寫轉換

 

3.3 sed用法演示

3.3.1 經常使用選項options演示

[root@along ~]# cat demo 
aaa
bbbb
AABBCCDD
[root@along ~]# sed "/aaa/p" demo  #匹配到的行會打印一遍,不匹配的行也會打印
aaa
aaa
bbbb
AABBCCDD
[root@along ~]# sed -n "/aaa/p" demo  #-n不顯示沒匹配的行
aaa
[root@along ~]# sed -e "s/a/A/" -e "s/b/B/" demo  #-e多點編輯
Aaa
Bbbb
AABBCCDD
[root@along ~]# cat sedscript.txt 
s/A/a/g
[root@along ~]# sed -f sedscript.txt demo  #-f使用文件處理
aaa
bbbb
aaBBCCDD
[root@along ~]# sed -i.bak "s/a/A/g" demo  #-i直接對文件進行處理
[root@along ~]# cat demo
AAA
bbbb
AABBCCDD
[root@along ~]# cat demo.bak
aaa
bbbb
AABBCCDD

  

3.3.2 地址界定演示

[root@along ~]# cat demo
aaa
bbbb
AABBCCDD
[root@along ~]# sed -n "p" demo  #不指定行,打印全文
aaa
bbbb
AABBCCDD
[root@along ~]# sed "2s/b/B/g" demo  #替換第2行的b->B
aaa
BBBB
AABBCCDD
[root@along ~]# sed -n "/aaa/p" demo
aaa
[root@along ~]# sed -n "1,2p" demo  #打印1-2行
aaa
bbbb
[root@along ~]# sed -n "/aaa/,/DD/p" demo
aaa
bbbb
AABBCCDD
[root@along ~]# sed -n "2,/DD/p" demo
bbbb
AABBCCDD
[root@along ~]# sed "1~2s/[aA]/E/g" demo  #將奇數行的a或A替換爲E
EEE
bbbb
EEBBCCDD

  

3.3.3 編輯命令command演示

[root@along ~]# cat demo
aaa
bbbb
AABBCCDD
[root@along ~]# sed "2d" demo  #刪除第2行
aaa
AABBCCDD
[root@along ~]# sed -n "2p" demo  #打印第2行
bbbb
[root@along ~]# sed "2a123" demo  #在第2行後加123
aaa
bbbb
123
AABBCCDD
[root@along ~]# sed "1i123" demo  #在第1行前加123
123
aaa
bbbb
AABBCCDD
[root@along ~]# sed "3c123\n456" demo  #替換第3行內容
aaa
bbbb
123
456
[root@along ~]# sed -n "3w/root/demo3" demo  #保存第3行的內容到demo3文件中
[root@along ~]# cat demo3 
AABBCCDD
[root@along ~]# sed "1r/root/demo3" demo  #讀取demo3的內容到第1行後
aaa
AABBCCDD
bbbb
AABBCCDD
[root@along ~]# sed -n "=" demo  #=打印行號
1
2
3
[root@along ~]# sed -n '2!p' demo  #打印除了第2行的內容
aaa
AABBCCDD
[root@along ~]# sed 's@[a-z]@\u&@g' demo  #將全文的小寫字母替換爲大寫字母
AAA
BBBB
AABBCCDD

  

3.4 sed高級編輯命令

1)格式

  •  h:把模式空間中的內容覆蓋至保持空間中
  •  H:把模式空間中的內容追加至保持空間中
  •  g:從保持空間取出數據覆蓋至模式空間
  •  G:從保持空間取出內容追加至模式空間
  •  x:把模式空間中的內容與保持空間中的內容進行互換
  •  n:讀取匹配到的行的下一行覆蓋 至模式空間
  •  N:讀取匹配到的行的下一行追加 至模式空間
  •  d:刪除模式空間中的行
  •  D:刪除 當前模式空間開端至\n 的內容(再也不傳 至標準輸出),放棄以後的命令,可是對剩餘模式空間從新執行sed

 

2)一個案例+示意圖演示

案例:倒序輸出文本內容

[root@along ~]# cat num.txt 
One
Two
Three
[root@along ~]# sed '1!G;h;$!d' num.txt
Three
Two
One

示意圖以下:

總結模式空間與保持空間關係:

保持空間是模式空間一個臨時存放數據的緩衝區,協助模式空間進行數據處理

 

3)演示

顯示偶數行

[root@along ~]# seq 9 |sed -n 'n;p'
2
4
6
8

倒序顯示

[root@along ~]# seq 9 |sed  '1!G;h;$!d'
9
8
7
6
5
4
3
2
1

顯示奇數行

[root@along ~]# seq 9 |sed 'H;n;d' 
1
3
5
7
9

顯示最後一行

[root@along ~]# seq 9| sed 'N;D'
9

每行之間加空行

[root@along ~]# seq 9 |sed 'G'
1

2

3

4

5

6

7

8

9

---

 ⑥ 把每行內容替換成空行

[root@along ~]# seq 9 |sed "g"









---

 ⑦ 確保每一行下面都有一個空行

[root@along ~]# seq 9 |sed '/^$/d;G'
1

2

3

4

5

6

7

8

9

 

四、awk

4.1 認識awk

  awk是一種編程語言,用於在linux/unix下對文本和數據進行處理。數據能夠來自標準輸入(stdin)、一個或多個文件,或其它命令的輸出。它支持用戶自定義函數和動態正則表達式等先進功能,是linux/unix下的一個強大編程工具。它在命令行中使用,但更可能是做爲腳原本使用。awk有不少內建的功能,好比數組、函數等,這是它和C語言的相同之處,靈活性是awk最大的優點。

  awk其實不只僅是工具軟件,仍是一種編程語言。不過,本文只介紹它的命令行用法,對於大多數場合,應該足夠用了。

 

4.2 使用awk

4.2.1 語法

awk [options] 'program' var=value file…
awk [options] -f programfile var=value file…
awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ...

  

4.2.2 經常使用命令選項

  •  -F fsfs指定輸入分隔符,fs能夠是字符串或正則表達式,如-F:
  •  -v var=value:賦值一個用戶定義變量,將外部變量傳遞給awk
  •  -f scripfile:從腳本文件中讀取awk命令

 

4.3 awk變量

變量:內置和自定義變量,每一個變量前加 -v 命令選項

4.3.1 內置變量

1)格式

  •  FS 輸入字段分隔符默認爲空白字符
  •  OFS 輸出字段分隔符,默認爲空白字符
  •  RS 輸入記錄分隔符,指定輸入時的換行符,原換行符仍有效
  •  ORS 輸出記錄分隔符,輸出時用指定符號代替換行符
  •  NF :字段數量,共有多少字段, $NF引用最後一列,$(NF-1)引用倒數第2
  •  NR 行號,後可跟多個文件,第二個文件行號繼續從第一個文件最後行號開始
  •  FNR :各文件分別計數, 行號,後跟一個文件和NR同樣,跟多個文件,第二個文件行號從1開始
  •  FILENAME 當前文件名
  •  ARGC 命令行參數的個數
  •  ARGV :數組,保存的是命令行所給定的各參數,查看參數

 

2)演示

[root@along ~]# cat awkdemo 
hello:world
linux:redhat:lalala:hahaha
along:love:youou
[root@along ~]# awk -v FS=':' '{print $1,$2}' awkdemo  #FS指定輸入分隔符
hello world
linux redhat
along love
[root@along ~]# awk -v FS=':' -v OFS='---' '{print $1,$2}' awkdemo  #OFS指定輸出分隔符
hello---world
linux---redhat
along---love
[root@along ~]# awk -v RS=':' '{print $1,$2}' awkdemo
hello 
world linux
redhat 
lalala 
hahaha along
love 
you
[root@along ~]# awk -v FS=':' -v ORS='---' '{print $1,$2}' awkdemo
hello world---linux redhat---along love---
[root@along ~]# awk -F: '{print NF}' awkdemo
2
4
3
[root@along ~]# awk -F: '{print $(NF-1)}' awkdemo  #顯示倒數第2列
hello
lalala
love
[root@along ~]# awk '{print NR}' awkdemo awkdemo1
1
2
3
4
5
[root@along ~]# awk END'{print NR}' awkdemo awkdemo1
5
[root@along ~]# awk '{print FNR}' awkdemo awkdemo1
1
2
3
1
2
[root@along ~]# awk '{print FILENAME}' awkdemo
awkdemo
awkdemo
awkdemo
[root@along ~]# awk 'BEGIN {print ARGC}' awkdemo awkdemo1
3
[root@along ~]# awk 'BEGIN {print ARGV[0]}' awkdemo awkdemo1
awk
[root@along ~]# awk 'BEGIN {print ARGV[1]}' awkdemo awkdemo1
awkdemo
[root@along ~]# awk 'BEGIN {print ARGV[2]}' awkdemo awkdemo1
awkdemo1

  

4.3.2 自定義變量

自定義變量( 區分字符大小寫)

1-v var=value

先定義變量,後執行動做print

[root@along ~]# awk -v name="along" -F: '{print name":"$0}' awkdemo
along:hello:world
along:linux:redhat:lalala:hahaha
along:along:love:you

在執行動做print後定義變量

[root@along ~]# awk -F: '{print name":"$0;name="along"}' awkdemo
:hello:world
along:linux:redhat:lalala:hahaha
along:along:love:you

  

2)在program 中直接定義

能夠把執行的動做放在腳本中,直接調用腳本 -f

[root@along ~]# cat awk.txt
{name="along";print name,$1}
[root@along ~]# awk -F: -f awk.txt awkdemo
along hello
along linux
along along

  

4.4 printf命令

print更強大

4.4.1 格式

1)格式化輸出

printf "FORMAT", item1,item2, ...

①  必須指定FORMAT

②  不會自動換行,須要顯式給出換行控制符,\n

③  FORMAT 中須要分別爲後面每一個item 指定格式符

 

2)格式符:與item 一一對應

  •  %c:  顯示字符的ASCII
  •  %d, %i:  顯示十進制整數
  •  %e, %E: 顯示科學計數法數值
  •  %f :顯示爲浮點數,小數   %5.1f,帶整數、小數點、整數共5位,小數1位,不夠用空格補上
  •  %g, %G :以科學計數法或浮點形式顯示數值
  •  %s :顯示字符串;例:%5s最少5個字符,不夠用空格補上,超過5個還繼續顯示
  •  %u :無符號整數
  •  %%:  顯示% 自身

 

3)修飾符:放在%c[/d/e/f...]之間

  •  #[.#]:第一個數字控制顯示的寬度;第二個# 表示小數點後精度,%5.1f
  •  -:左對齊(默認右對齊 %-15s
  •  +:顯示數值的正負符號 %+d

 

4.4.2 演示

[root@along ~]# awk -F: '{print $1,$3}' /etc/passwd
root 0
bin 1
---第一列顯示小於20的字符串;第2列顯示整數並換行
[root@along ~]# awk -F: '{printf "%20s---%u\n",$1,$3}' /etc/passwd
                root---0
                 bin---1
---使用-進行左對齊;第2列顯示浮點數
[root@along ~]# awk -F: '{printf "%-20s---%-10.3f\n",$1,$3}' /etc/passwd
root                ---0.000     
bin                 ---1.000
---使用printf作表格
[root@along ~]# awk -F: 'BEGIN{printf "username            userid\n-----------------------------\n"}{printf "%-20s|%-10.3f\n",$1,$3}' /etc/passwd
username            userid
-----------------------------
root                |0.000     
bin                 |1.000

  

4.5 操做符

4.5.1 格式

  •  算術操做符:
    •  x+y, x-y, x*y, x/y, x^y, x%y
    •  -x:  轉換爲負數
    •  +x:  轉換爲數值
  •  字符串操做符:沒有符號的操做符,字符串鏈接
  •  賦值操做符:
    •  =, +=, -=, *=, /=, %=, ^=
    •  ++, --
  •  比較操做符:
    •  ==, !=, >, >=, <, <=
  •  模式匹配符:~ :左邊是否和右邊匹配包含 !~ :是否不匹配
  •  邏輯操做符:與&& ,或|| ,非!
  •  函數調用: function_name(argu1, argu2, ...)
  •  條件表達式(三目表達式):selector?if-true-expression:if-false-expression
    •  註釋:先判斷selector,若是符合執行 ? 後的操做;不然執行 : 後的操做

 

4.5.2 演示

1)模式匹配符

---查詢以/dev開頭的磁盤信息
[root@along ~]# df -h |awk -F: '$0 ~ /^\/dev/'
/dev/mapper/cl-root   17G  7.3G  9.7G  43% /
/dev/sda1           1014M  121M  894M  12% /boot
---只顯示磁盤使用情況和磁盤名
[root@along ~]# df -h |awk '$0 ~ /^\/dev/{print $(NF-1)"---"$1}'
43%---/dev/mapper/cl-root
12%---/dev/sda1
---查找磁盤大於40%的
[root@along ~]# df -h |awk '$0 ~ /^\/dev/{print $(NF-1)"---"$1}' |awk -F% '$1 > 40'
43%---/dev/mapper/cl-root

  

2)邏輯操做符

[root@along ~]# awk -F: '$3>=0 && $3<=1000 {print $1,$3}' /etc/passwd
root 0
bin 1
[root@along ~]# awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd
root
[root@along ~]# awk -F: '!($3==0) {print $1}' /etc/passwd
bin
[root@along ~]# awk -F: '!($0 ~ /bash$/) {print $1,$3}' /etc/passwd
bin 1
daemon 2

  

3)條件表達式(三目表達式)

[root@along ~]# awk -F: '{$3 >= 1000?usertype="common user":usertype="sysadmin user";print usertype,$1,$3}' /etc/passwd
sysadmin user root 0
common user along 1000

  

4.6 awk PATTERN 匹配部分

4.6.1 格式

PATTERN:根據pattern 條件,過濾匹配的行,再作處理

1)若是未指定:空模式,匹配每一行

2/regular expression/ :僅處理可以模式匹配到的行,正則,須要用/ / 括起來

3relational expression關係表達式,結果爲纔會被處理

真:結果爲非0值,非空字符串

假:結果爲空字符串或0

4line ranges:行範圍

  startline(起始行),endline(結束行)/pat1/,/pat2/  不支持直接給出數字,能夠有多段,中間能夠有間隔

5BEGIN/END 模式

  BEGIN{}:  僅在開始處理文件中的文本以前執行一次

  END{} :僅在文本處理完成以後執行

 

4.6.2 演示

[root@along ~]# awk -F: '{print $1}' awkdemo
hello
linux
along
[root@along ~]# awk -F: '/along/{print $1}' awkdemo
along
[root@along ~]# awk -F: '1{print $1}' awkdemo
hello
linux
along
[root@along ~]# awk -F: '0{print $1}' awkdemo
[root@along ~]# awk -F: '/^h/,/^a/{print $1}' awkdemo
hello
linux
along
[root@along ~]# awk -F: 'BEGIN{print "第一列"}{print $1} END{print "結束"}' awkdemo
第一列
hello
linux
along
結束

  

4.7 awk有意思的案例

[root@along ~]# seq 10
1
2
3
4
5
6
7
8
9
10
---由於i=0,爲假,因此不打印
[root@along ~]# seq 10 |awk 'i=0'
---i=1,爲真,因此所有打印
[root@along ~]# seq 10 |awk 'i=1'
1
2
3
4
5
6
7
8
9
10
---只打印奇數行;奇數行i進入時自己爲空,被賦爲!i,即不爲空,因此打印;偶數行i進入時自己不爲空,被賦爲!i,即爲空,因此不打印
[root@along ~]# seq 10 |awk 'i=!i'
1
3
5
7
9
---解釋上一個操做,i在奇偶行的值
[root@along ~]# seq 10 |awk '{i=!i;print i}'
1
0
1
0
1
0
1
0
1
0
---只打印偶數行,是上邊打印奇數行的取反
[root@along ~]# seq 10 |awk '!(i=!i)'
2
4
6
8
10
---只打印偶數行;先對i進行賦值,即不爲空,恰好和打印奇數行相反
[root@along ~]# seq 10 |awk -v i=1 'i=!i'
2
4
6
8
10

  

五、awk高階用法

5.1 awk控制語句—if-else判斷

1)語法

if(condition){statement;…}[else statement]  雙分支
if(condition1){statement1}else if(condition2){statement2}else{statement3}  多分支

2)使用場景:對awk 取得的整行或某個字段作條件判斷

3)演示

[root@along ~]# awk -F: '{if($3>10 && $3<1000)print $1,$3}' /etc/passwd
operator 11
games 1
[root@along ~]# awk -F: '{if($NF=="/bin/bash") print $1,$NF}' /etc/passwd
root /bin/bash
along /bin/bash
---輸出總列數大於3的行
[root@along ~]# awk -F: '{if(NF>2) print $0}' awkdemo
linux:redhat:lalala:hahaha
along:love:you
---第3列>=1000爲Common user,反之是root or Sysuser
[root@along ~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else{printf "root or Sysuser: %s\n",$1}}' /etc/passwd
root or Sysuser: root
root or Sysuser: bin
Common user: along
---磁盤利用率超過40的設備名和利用率
[root@along ~]# df -h|awk -F% '/^\/dev/{print $1}'|awk '$NF > 40{print $1,$NF}'
/dev/mapper/cl-root 43
---test=100和>90爲very good; 90>test>60爲good; test<60爲no pass
[root@along ~]# awk 'BEGIN{ test=100;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}' 
very good
[root@along ~]# awk 'BEGIN{ test=80;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}' 
good
[root@along ~]# awk 'BEGIN{ test=50;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}' 
no pass

  

5.2 awk控制語句—while循環

1)語法

while(condition){statement;…}

注:條件,進入循環;條件, 退出循環

 

2)使用場景

  對一行內的多個字段逐一相似處理時使用

  對數組中的各元素逐一處理時使用

 

3)演示

---以along開頭的行,以:爲分隔,顯示每一行的每一個單詞和其長度
[root@along ~]# awk -F: '/^along/{i=1;while(i<=NF){print $i,length($i); i++}}' awkdemo
along 5
love 4
you 3
---以:爲分隔,顯示每一行的長度大於6的單詞和其長度
[root@along ~]# awk -F: '{i=1;while(i<=NF) {if(length($i)>=6){print $i,length($i)}; i++}}' awkdemo
redhat 6
lalala 6
hahaha 6
---計算1+2+3+...+100=5050
[root@along ~]# awk 'BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++};print sum}'
5050

  

5.3 awk控制語句—do-while循環

1)語法

do {statement;…}while(condition)

意義:不管真假,至少執行一次循環體

 

2)計算1+2+3+...+100=5050

[root@along ~]# awk 'BEGIN{sum=0;i=1;do{sum+=i;i++}while(i<=100);print sum}'
5050

  

5.4 awk控制語句—for循環

1)語法

for(expr1;expr2;expr3) {statement;…}

  

2)特殊用法:遍歷數組中的元素

for(var in array) {for-body}

  

3)演示

---顯示每一行的每一個單詞和其長度
[root@along ~]# awk -F: '{for(i=1;i<=NF;i++) {print$i,length($i)}}' awkdemo
hello 5
world 5
linux 5
redhat 6
lalala 6
hahaha 6
along 5
love 4
you 3
---求男m、女f各自的平均
[root@along ~]# cat sort.txt 
xiaoming m 90
xiaohong f 93
xiaohei m 80
xiaofang f 99
[root@along ~]# awk '{m[$2]++;score[$2]+=$3}END{for(i in m){printf "%s:%6.2f\n",i,score[i]/m[i]}}' sort.txt
m: 85.00
f: 96.00

  

5.5 shell腳本中較類似的控制語句

5.5.1 switch語句

shell中的case很像,就不在演示了

switch(expression) {case VALUE1 or /REGEXP/:statement1; case VALUE2 or /REGEXP2/: statement2;...; default: statementn}

 

5.5.2 breakcontinue

---奇數相加
[root@along ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}'
2500
---1+2+...+66
[root@along ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}'
2145

 

5.5.3 next

next:提早結束對本行處理而直接進入下一行處理(awk 自身循環)

---只打印偶數行
[root@along ~]# awk -F: '{if(NR%2!=0) next; print $1,$3}' /etc/passwd
bin 1
adm 3

  

5.6 awk數組

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

1)可以使用任意字符串;字符串要使用雙引號括起來

2)若是某數組元素事先不存在,在引用時,awk 會自動建立此元素,並將其值初始化爲空串

3)若要判斷數組中是否存在某元素,要使用「index in array」格式進行遍歷

4)若要遍歷數組中的每一個元素,要使用for 循環for(var in array) {for-body}

 

5.6.2 演示

1awk使用數組

[root@along ~]# cat awkdemo2
aaa
bbbb
aaa
123
123
123
---去除重複的行
[root@along ~]# awk '!arr[$0]++' awkdemo2
aaa
bbbb
123
---打印文件內容,和該行重複第幾回出現
[root@along ~]# awk '{!arr[$0]++;print $0,arr[$0]}' awkdemo2
aaa 1
bbbb 1
aaa 2
123 1
123 2
123 3

  分析:把每行做爲下標,第一次進來,至關於print ias...同樣結果爲空,打印空,!取反結果爲1,打印本行,而且++變爲不空,下次進來相同的行就是相同的下標,原本上次的值,!取反爲空,不打印,++變爲不空,因此每次重複進來的行都不打印

 

2)數組遍歷

[root@along ~]# awk 'BEGIN{abc["ceo"]="along";abc["coo"]="mayun";abc["cto"]="mahuateng";for(i in abc){print i,abc[i]}}'
coo mayun
ceo along
cto mahuateng
[root@along ~]# awk '{for(i=1;i<=NF;i++)abc[$i]++}END{for(j in abc)print j,abc[j]}' awkdemo2
aaa 2
bbbb 1
123 3

  

5.6.3 數值\字符串處理

1)數值處理

  •  rand():返回01之間一個隨機數,需有個種子 srand(),沒有種子,一直輸出0.237788

演示:

[root@along ~]# awk 'BEGIN{print rand()}'
0.237788
[root@along ~]# awk 'BEGIN{srand(); print rand()}'
0.51692
[root@along ~]# awk 'BEGIN{srand(); print rand()}'
0.189917
---取0-50隨機數
[root@along ~]# awk 'BEGIN{srand(); print int(rand()*100%50)+1}'
12
[root@along ~]# awk 'BEGIN{srand(); print int(rand()*100%50)+1}'
24

  

2)字符串處理:

  •  length([s]) :返回指定字符串的長度
  •  sub(r,s,[t]) :對t 字符串進行搜索r 表示的模式匹配的內容,並將第一個匹配的內容替換爲s
  •  gsub(r,s,[t]) :對t 字符串進行搜索r 表示的模式匹配的內容,並所有替換s 所表示的內容
  •  plit(s,array,[r]) :以r 爲分隔符,切割字符串s ,並將切割後的結果保存至array 所表示的數組中,第一個索引值爲1, 第二個索引值爲2,…

演示:

[root@along ~]# echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
2008-08:08 08:08:08
[root@along ~]# echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
2008-08-08 08-08-08
[root@along ~]# echo "2008:08:08 08:08:08" | awk '{split($0,i,":")}END{for(n in i){print n,i[n]}}'
4 08
5 08
1 2008
2 08
3 08 08

  

5.7 awk自定義函數

1)格式:和bash區別:定義函數()中需加參數,return返回值不是$?,是至關於echo輸出

function name ( parameter, parameter, ... ) {
    statements
    return expression
}

  

2)演示

[root@along ~]# cat fun.awk 
function max(v1,v2) {
	v1>v2?var=v1:var=v2
	return var
}
BEGIN{a=3;b=2;print max(a,b)}
[root@along ~]# awk -f fun.awk 
3

  

5.8 awk中調用shell 命令

1system 命令

  空格是awk 中的字符串鏈接符,若是system中須要使用awk中的變量可使用空格分隔,或者說除了awk 的變量外其餘一概用"" 引用 起來。

[root@along ~]# awk BEGIN'{system("hostname") }'
along
[root@along ~]# awk 'BEGIN{name="along";system("echo "name)}'  注:"echo " echo後有空格
along
[root@along ~]# awk 'BEGIN{score=100; system("echo your score is " score) }'
your score is 100

  

2awk 腳本

awk 程序寫成腳本,直接調用或執行

示例:

[root@along ~]# cat f1.awk 
{if($3>=1000)print $1,$3}
[root@along ~]# cat f2.awk 
#!/bin/awk -f
{if($3 >= 1000)print $1,$3}
[root@along ~]# chmod +x f2.awk
[root@along ~]# ./f2.awk -F: /etc/passwd
along 1000

  

3)向awk腳本傳遞參數

格式:

awkfile var=value var2=value2... Inputfile

  注意 :在BEGIN 過程 中不可用。直到 首行輸入完成之後,變量纔可用 。能夠經過-v  參數,讓awk 在執行BEGIN 以前獲得變量的值。命令行中每個指定的變量都須要一個-v

示例

[root@along ~]# cat test.awk 
#!/bin/awk -f
{if($3 >=min && $3<=max)print $1,$3}
[root@along ~]# chmod +x test.awk
[root@along ~]# ./test.awk -F: min=100 max=200 /etc/passwd
systemd-network 192

  

六、grep awk sed對比

grep 主要用於搜索某些字符串;

sedawk 用於處理文本 ;

  grep基本是以行爲單位處理文本的 awk能夠作更細分的處理,經過指定分隔符將一行(一條記錄)劃分爲多個字段,以字段爲單位處理文本。awk中支持C語法,能夠有分支條件判斷、循環語句等,至關於一個小型編程語言。

  awk功能比較可能是一個編程語言了。 grep功能簡單,就是一個簡單的正則表達式的匹配。 awk的功能依賴於grep

  grep能夠理解爲主要做用是在一個文件中查找過濾須要的內容awk不是過濾查找,而是文本處理工具,是把一個文件處理成你想要的格式。

  AWK的功能是什麼?與sedgrep很類似,awk是一種樣式掃描與處理工具。但其功能卻大大強於sedgrepawk提供了極其強大的功能:它幾乎能夠完成grepsed所能完成的所有工做,同時,它還能夠能夠進行樣式裝入、流控制、數學運算符、進程控制語句甚至於內置的變量和函數。它具有了一個完整的語言所應具備的幾乎全部精美特性。實際上,awk的確擁有本身的語言:awk程序設計語言,awk的三位建立者已將它正式定義爲:樣式掃描和處理語言。  使用awk的第一個理由是基於文本的樣式掃描和處理是咱們常常作的工做,awk所作的工做有些象數據庫,但與數據庫不一樣的是,它處理的是文本文件,這些文件沒有專門的存儲格式,普通的人們就能編輯、閱讀、理解和處理它們。而數據庫文件每每具備特殊的存儲格式,這使得它們必須用數據庫處理程序來處理它們。既然這種相似於數據庫的處理工做咱們常常會遇到,咱們就應當找處處理它們的簡便易行的方法,UNIX有不少這方面的工具,例如sed grepsort以及find等等,awk是其中十分優秀的一種。 

  使用awk的第二個理由是awk是一個簡單的工具,固然這是相對於其強大的功能來講的。的確,UNIX有許多優秀的工具,例如UNIX自然的開發工具C語言及其延續C++就很是的優秀。但相對於它們來講,awk完成一樣的功能要方便和簡捷得多。這首先是由於awk提供了適應多種須要的解決方案:從解決簡單問題的awk命令行到複雜而精巧的awk程序設計語言,這樣作的好處是,你能夠沒必要用複雜的方法去解決原本很簡單的問題。例如,你能夠用一個命令行解決簡單的問題,而C不行,即便一個再簡單的程序,C語言也必須通過編寫、編譯的全過程。其次,awk自己是解釋執行的,這就使得awk程序沒必要通過編譯的過程,同時,這也使得它與shell script程序可以很好的契合。最後,awk自己較C語言簡單,雖然awk吸取了C語言不少優秀的成分,熟悉C語言會對學習awk有很大的幫助,但awk自己不需要會使用C語言——一種功能強大但須要大量時間學習才能掌握其技巧的開發工具。 

  使用awk的第三個理由是awk是一個容易得到的工具。與CC++語言不一樣,awk只有一個文件(/bin/awk),並且幾乎每一個版本的UNIX都提供各自版本的awk,你徹底沒必要費心去想如何得到awk。但C語言卻不是這樣,雖然C語言是UNIX自然的開發工具,但這個開發工具倒是單獨發行的,換言之,你必須爲你的UNIX版本的C語言開發工具單獨付費(固然使用D版者除外),得到並安裝它,而後你纔可使用它。 

  基於以上理由,再加上awk強大的功能,咱們有理由說,若是你要處理與文本樣式掃描相關的工做,awk應該是你的第一選擇。在這裏有一個可遵循的通常原則:若是你用普通的shell工具或shell script有困難的話,試試awk,若是awk仍不能解決問題,則便用C語言,若是C語言仍然失敗,則移至C++ 

  sed是一個非交互性文本流編輯器。它編輯文件或標準輸入導出的文本拷貝。sed編輯器按照一次處理 一行的方式來處理文件(或者輸入)並把輸出送到屏幕上。你能夠在viex/ed編輯器裏識別他的命令。sed把當前正在處理的行保存在一個臨時緩存裏,這個緩存叫作模式空間。一但sed完成了對模式空間裏的行的處理(即對該行執行sed命令),就把模式空間的行送到屏幕上(除非該命令要刪除該行活禁止打印)。處理完該行以後,從模式空間裏刪除它,而後把下一行讀入模式空間,進行處理,並顯示。當輸入文件的最後一行處理完後,sed終止。經過把每一行存在一個臨時緩存裏並編輯該行,初始文件不會被修改或被破壞。

相關文章
相關標籤/搜索