鍍金池/ 教程/ Linux/ shell 學(xué)習(xí)第十七天----awk 命令
shell 學(xué)習(xí)四十一天----列出文件 ls 和 od 命令
shell 學(xué)習(xí)小結(jié)
shell 學(xué)習(xí)第二十八天----case 語句
shell 學(xué)習(xí)四十四天----尋找文件
shell 學(xué)習(xí)三十五天----波浪號(hào)展開與通配符
shell 學(xué)習(xí)三十八天----執(zhí)行順序和 eval
shell 學(xué)習(xí)四十八天----文件校驗(yàn)和匹配
shell 學(xué)習(xí)四十天----awk 的驚人表現(xiàn)
shell 學(xué)習(xí)第十一天----sed 正則的精確控制
shell 學(xué)習(xí)第十七天----awk 命令
shell 學(xué)習(xí)三十九天----內(nèi)建命令
shell 學(xué)習(xí)四十五天----xargs
shell 學(xué)習(xí)三十七天----引用
shell 學(xué)習(xí)第十六天----join 練習(xí)
shell 學(xué)習(xí)第二十四天----提取開頭或結(jié)尾數(shù)行
shell 學(xué)習(xí)第九天----分組
shell 學(xué)習(xí)第五天----基本的 I/O 重定向
shell 學(xué)習(xí)第十五天----使用 cut 選定字段
shell 學(xué)習(xí)四十六天----文件系統(tǒng)的空間信息 df 和 du 命令
shell 學(xué)習(xí)第八天----擴(kuò)展正則表達(dá)式 (ERE)
shell 學(xué)習(xí)第十九天----文本塊排序
shell 學(xué)習(xí)第二十一天----重新格式化段落
shell 學(xué)習(xí)三十六天----命令替換
shell 學(xué)習(xí)第二十天----sort 的其他內(nèi)容以及 uniq 命令
shell 學(xué)習(xí)四十二天----使用 touch 更新文件時(shí)間
shell 學(xué)習(xí)五十一天----top 命令查看進(jìn)程列表
shell 學(xué)習(xí)第一天
shell 學(xué)習(xí)五十四天----進(jìn)程系統(tǒng)調(diào)用的追蹤 strace
shell 學(xué)習(xí)五十天----查看進(jìn)程 ps 命令
shell 學(xué)習(xí)第二十七天----退出狀態(tài)和 if 語句
shell 學(xué)習(xí)第二十三天----打印
shell 學(xué)習(xí)三十三天----關(guān)于重定向
shell 學(xué)習(xí)四十九天----進(jìn)程建立
shell 學(xué)習(xí)第三十天----break,continue,shift,getopts
shell 學(xué)習(xí)五十五天----進(jìn)程記賬
shell 學(xué)習(xí)總結(jié)一
shell 學(xué)習(xí)第二十六天----變量與算數(shù)
shell 學(xué)習(xí)第二十二天----計(jì)算行數(shù), 字?jǐn)?shù)以及字符數(shù)
shell 學(xué)習(xí)五十八天----/proc 文件系統(tǒng)
shell 學(xué)習(xí)第二十五天----神器的管道符
shell 學(xué)習(xí)第三十二天----read 讀取一行
sheel 學(xué)習(xí)第三天
shell 學(xué)習(xí)----小結(jié)
shell 學(xué)習(xí)第十八天----文本排序
shell 學(xué)習(xí)第三十一天----函數(shù)問題
shell 學(xué)習(xí)第十天----sed 查找與替換
shell 學(xué)習(xí)四十三天----臨時(shí)性文件的建立與使用
shell 學(xué)習(xí)四十七天----文件比較 cmp,diff,patch
shell 學(xué)習(xí)三十四天----printf 詳解
shell 學(xué)習(xí)五十七天 ----linux 任務(wù)管理,針對(duì)上一講的總結(jié)和擴(kuò)展
shell 學(xué)習(xí)第六天----小結(jié)
shell 學(xué)習(xí)第十三天----sed 案例分析
shell 學(xué)習(xí)第七天----基礎(chǔ)正則表達(dá)式 (BRE)
shell 學(xué)習(xí)第十二天----行與字符串
shell 學(xué)習(xí)小結(jié)四
shell 學(xué)習(xí)第二十九天----循環(huán)
shell 學(xué)習(xí)五十二天----刪除進(jìn)程 kill 命令
shell 學(xué)習(xí)五十六天----延遲進(jìn)程調(diào)度
shell 學(xué)習(xí)第四天----華麗的 printf 輸出
shell 學(xué)習(xí)第十五天----join 連接字段
shell 學(xué)習(xí)完結(jié)篇----希望你能看到
shell 學(xué)習(xí)第二天
shell 學(xué)習(xí)五十三天----捕獲信號(hào) trap

shell 學(xué)習(xí)第十七天----awk 命令

shell 學(xué)習(xí)第十七天----awk 命令

使用 awk 重新編排字段

awk 非常擅長處理結(jié)構(gòu)化數(shù)據(jù)和生成表單。和 sed 和 grep 很相似。由于 awk 具備各種及哦啊本語言的特點(diǎn),所以可以把它看做是一種腳本語言。

先來看個(gè)案例,只查看 /etc/passwd/ 目錄下的用戶名和組名

awk -F: ‘{print $1,$5}’ /etc/passwd

意思是: 使用: 來分割這一行,把這一行的第一和第五個(gè)字段打印出來。

調(diào)用 awk

  • 第一種方式:awk [-F 分隔符] 'commands' input-file(s) 這里的 commands 是真正的 awk 命令,[-F 分隔符] 適可選的,awk 默認(rèn)使用空格分隔,因此如果要瀏覽域間有空格的文本,不必指定這個(gè)選項(xiàng),但如果瀏覽如 passwd 文件,此文件各域使用冒號(hào)作為分隔符,則必須使用 -F 選項(xiàng): awk -F : 'commands' input-file
  • 第二種方式:將所有 awk 命令插入一個(gè)文件,并使 awk 程序可執(zhí)行,然后用 awk 命令解釋器作為腳本的首行,以便通過鍵入腳本名稱來調(diào)用它
  • 第三種方式:將所有 awk 命令插入一個(gè)單獨(dú)文件,然后調(diào)用,如: awk -f awk-script-file input-file-f 選項(xiàng)指明在文件 awk-script-fileawk 腳本,input-file 是使用 awk 進(jìn)行瀏覽的文件名

任何 awk 語句都是由模式和動(dòng)作組成,在一個(gè) awk 腳本中可能有許多語句。模式部分決定動(dòng)作語句何時(shí)觸發(fā)及觸發(fā)事件。動(dòng)作即對(duì)數(shù)據(jù)進(jìn)行的操作,如果省去模式部分,動(dòng)作將時(shí)刻保持執(zhí)行狀態(tài)。

模式可以是任何條件語句或復(fù)合語句或正則表達(dá)式,模式包含兩個(gè)特殊字段 BEGINEND,使用 BEGIN 語句設(shè)置計(jì)數(shù)和打印頭,BEGIN 語句使用在任何文本瀏覽動(dòng)作之前,之后文本瀏覽動(dòng)作依據(jù)輸入文件開始執(zhí)行;END 語句用來在 awk 完成文本瀏覽動(dòng)作后打印輸出文本總數(shù)和結(jié)尾狀態(tài)標(biāo)志,有動(dòng)作必須使用 {} 括起來

實(shí)際動(dòng)作在大括號(hào) {} 內(nèi)指明,常用來做打印動(dòng)作,但是還有更長的代碼如 if 和循環(huán) looping 語句及循環(huán)退出等,如果不指明采取什么動(dòng)作,awk 默認(rèn)打印出所有瀏覽出的記錄

awk 執(zhí)行時(shí),其瀏覽標(biāo)記為 $1,$2...$n,這種方法稱為域標(biāo)記。使用 $1,$3 表示參照第 1 和第 3 域,注意這里使用逗號(hào)分隔域,使用 $0 表示使用所有域。例

  • awk -F :‘{print $0}’ /etc/passwd // 表示打印所有域并把結(jié)果重定向到 /etc/passwd 中 (所謂的域就是某一行中的字段)

  • awk -F : ‘{print $0}’ /etc/passwd /// 在屏幕上顯示出來

  • awk ‘{print $1,$4}’ /etc/passwd // 只打印第一和第四域 (第一和第四字段)

  • awk -F: ‘BRGIN{print”hahaha\n---”}{print $1 “\t” $4}’ /etc/passwd // 表示打印頭信息,在輸入的內(nèi)容的第一行前加上”hahaha”,同時(shí)內(nèi)容之間用 tab 鍵分開。

  • awk -F: 'BEGIN{print"hahaha\n---"}{print $1"\t"$4}END{print"end\n"}' /etc/passwd // 這個(gè)代表的意思是說打印開頭結(jié)尾

awk 的條件匹配符

<、<=、==、!=、>=、~ 匹配正則表達(dá)式、!~ 不匹配正則表達(dá)式

  • 匹配:awk -F: '{if($1~/root/)print $0}' /etc/passwd // 在 /etc/passwd 這個(gè)文件中,如果某條記錄的第一個(gè)字段含有 root 就打印整條記錄到屏幕上,注意,只要包含就行。
  • 精確匹配 :awk -F: '$1=="root"{print $0}' /etc/passwd // 某行中的第一個(gè)字段必須等于 root 才打印。
  • 不匹配 : awk -F: '$0!~"root"{print $0}' /etc/passwd 打印整條不包含 root 的記錄,使用雙引號(hào)或者反斜杠都是一樣的。

其他的操作符具體不在介紹。

awk 的設(shè)計(jì)目的就是操作記錄與字段:awk 讀取輸入記錄 (通常是一些行),然后自動(dòng)將各個(gè)記錄且分為字段。awk 將每條記錄內(nèi)的字段樹木,存儲(chǔ)到內(nèi)建變量 NF。通過上面的例子,差不多已經(jīng)總體上有了一定得了解:awk '{print $NF}' 打印最后一行,比較特殊的字段是編號(hào) 0,表示整條記錄。

awk 內(nèi)置變量

ARGC               命令行參數(shù)個(gè)數(shù)
ARGV               命令行參數(shù)排列
ENVIRON            支持隊(duì)列中系統(tǒng)環(huán)境變量的使用
FILENAME           awk 瀏覽的文件名
FNR                瀏覽文件的記錄數(shù)
FS                 設(shè)置輸入域分隔符,等價(jià)于命令行 -F 選項(xiàng)
NF                 瀏覽記錄的域的個(gè)數(shù)
NR                 已讀的記錄數(shù)
OFS                輸出域分隔符
ORS                輸出記錄分隔符
RS                 控制記錄分隔符

案例

統(tǒng)計(jì) /etc/passwd: 文件名,每行的行號(hào),每行的列數(shù),對(duì)應(yīng)的完整行內(nèi)容:

awk -F ':' '{print"filename:"FILENAME",linenumber:"NR",columns:"NF",linecontent:"$0}' /etc/passwd

除了 awk 的內(nèi)置變量,awk 還可以自定義變量。

例如:

統(tǒng)計(jì) /etc/passwd 的行數(shù)

awk '{count++}END{print  count}' /etc/passwd
count 是自定義變量,這里沒有初始化 count,雖然默認(rèn)是 0,但是妥當(dāng)?shù)淖龇ㄟ€是初始化為 0。
awk 'BEGIN{count=0}{count=count+1}END{print count}' /etc/passwd

例如:

統(tǒng)計(jì)某個(gè)文件夾下的文件占用的字節(jié)數(shù)

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print"[end]size is ",size}'

如果按照 M 為單位顯示

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print"[end]size is ",size/1024/1024,"M"}'

小結(jié)

  • 如果需要從輸入的數(shù)據(jù)文件夾中取出特定的文本行,主要的工具為 grep 程序。
  • sed 是處理簡單字符串替換的主要工具。大部分 shell 腳本在使用 sed 時(shí)幾乎都是用來做替換的操作。
  • “從最左邊開始,擴(kuò)展至最長” 這個(gè)法則描述了匹配的文本在何處匹配以及匹配擴(kuò)展到多長。在使用 sed,awk 或其他交互式文本編輯程序時(shí),這個(gè)法則相當(dāng)重要。
  • cut 命令用以剪下選定的字符范圍或字段。join 則是用來結(jié)合記錄中具有共同鍵值的字段的文件。
  • awk 多半用于簡單的“單命令行程序”,當(dāng)你想要只顯示選定的字段,或是重新安排行內(nèi)的字段順序時(shí),就是 awk 排上用場的時(shí)候了。由于 awk 還是編程語言,即使在尖端的程序里,他也能發(fā)揮強(qiáng)大的作用。