阿旺的 Linux 開竅手冊







基礎篇
進階篇
補腦篇
版權所有,引用請註明出處

 進階篇

Advanced Chapter 3 : sed 和 awk

3.0 sed 和 awk 簡介
3.1 sed 檔案字串修改
        sed 基本用法
        sed 進階用法
            delimiter 分隔符號
            ADDRESS 位址範圍
            OPTION 選項
            FLAG 旗幟
            流程控制
            COMMAND 命令
3.2 awk 文字記錄的資料處理
        awk 基本用法
        awk 程式模式
            自定變數
            內建變數
            BEGIN 和 END
            輸出函數 print 和 printf ( )
            關聯矩陣(Associative Arrays)
            system 執行系統指令
            close 關閉檔案/管線
            getline 讀入資料
            數學函數
            字串函數
            自定函數





















sed 和 awk

3.0 sed 和 awk 簡介

sed
awk 這兩大工具時常被拿來相提並論,因二者一樣強大和對正規表示法有良好的支援。也各自有自己專屬的腳本語言(script language),sed 主要功能為自動化的修改文字檔,而 awk 可想像為超輕量級的 C 直譯語言(Interpreted language)屬通用,偏向統計和需輸出重新排版的應用。

國內的中文書籍或網站在介紹 sedawk 多只講解簡單的應用和含糊帶過,且天下文章一大抄內容都大同小異,對想深入應用的 user 常找不到更詳細的資料。別太天真認為參考 man page 就可以,man page 是給已熟悉的人參考用的,用 man page 學 sedawk 就好像用英文字典學英文會話。所以這嘗試盡可能的把 sedawk 所有的功能和潛力寫出來。如是輕度的使用者不想浪費太多的時間,參考 sed 基本用法 awk 基本用法應足以應付 90 % 以上的需求。


^ back on top ^





3.1 sed 檔案字串修改

grep
雖可利用功能強大的正規表示法搜尋檔案中的字串,但沒辦法對搜尋到的字串進行刪除,取代或插入等編輯動作;補足 grep 編輯功能的工具就是 sed,更甚者 sed 可程式化的特性常用來自動化的修改文字檔。

雖然 vi 也可用來搜尋/修改檔案內容,但要人工把檔案打開,改完再存檔人力要介入很深,如熟悉 sed 的操作這些都可自動化的完成。例如公司搬家,有舊公司地址的表格文件一堆,如善用 sed 就可有效率的自動把所有文件表格上的舊地址改新地址。

sed 用法有點抽象,故對基本用法和每一參數分別說明。


^ back on top ^




3.2 awk 文字記錄的資料處理
許多的 UNIX/Linux 指令名稱都源自於很莫名奇怪的縮寫,awk 更是!其指令名稱來自其三位作者 Alfred Aho, Peter Weinberger 和 Brian Kernighan 的姓氏縮寫。

awk 為一直譯語言(Interpreter),大量引用 C 語言的語法,取 C 語言對文字處理和輸出格式的精華,再加上支援原始 C 語言所沒有的對正規表示法的匹配和關聯矩陣(Associative Arrays)的支援。

因此 awk 和 C 語言應用上最大的差別為 C 語言為通用的程式語言,指令和語法多而複雜,而 awk 小而精簡,特別適合用來處理和計算用文字記錄的資料和文字的排版。1980 年代 awk 曾很流行,一直到約 1990 才逐漸被另一通用的直譯語言 Perl 所瓜分。



^ back on top ^











www.reliablecounter.com
digital mastering

[註3.1]GNU sed 版本官網有許多精彩有用的 sed 程式範例,有興趣可參考 sed, a stream editor Examples 或 Bruce Barnett 寫的 Sed - An Introduction and Tutorial

[註3.2] 〝string ~ /regex/〞 此種寫法在 awk 執行時會展開為〝{if (string ~ /regex/) print}〞,所以寫成外部的 script 檔時〝string ~ /regex/〞此種寫法要去除最外面的"'{ }"。
(例如 awk '$8 ~ /pr*e/展開後等於 awk '{if ($8 ~ /pr*e/) print}')