標籤:

Linux中sed和awk的使用及其相關實例解析 | IT宅.com

如果對實例中涉及的相關Linux命令不了解,可以參考:Linux下sed,awk,grep,cut,find等常用命令介紹在每一行後面增加一空行sed方法:

sed G express

關於sed的幾個命令參數:G獲得內存緩衝區的內容(此時內存緩衝區是空的),並追加到當前模板塊文本的後面。

awk方法:

awk "{print $0 "
"}" express

關於awk:

awk是一種用於處理文本的編程語言工具。AWK 實用工具的語言在很多方面類似於 shell 編程語言,儘管 AWK 具有完全屬於其本身的語法。在最初創造 AWK 時,其目的是用於文本處理,並且這種語言的基礎是,只要在輸入數據中有模式匹配,就執行一系列指令。該實用工具掃描文件中的每一行,查找與命令行中所給定 內容相匹配的模式。如果發現匹配內容,則進行下一個編程步驟。如果找不到匹配內容,則繼續處理下一行。

awk命令的語法

awk "{pattern + action}" {filenames}

其中 pattern 表示 AWK 在數據中查找的內容,而 action 是在找到匹配內容時所執行的一系列命令。花括弧 ({}) 不需要在程序中始終出現,但它們用於根據特定的模式對一系列指令進行分組。

$0,關於awk的欄位

實用工具將每個輸入行分為記錄和欄位。記錄是單行的輸入,而每條記錄包含若干欄位。默認的欄位分隔符是空格或製表符,而記錄的分隔符是換行。雖然在默認情況下將製表符和空格都看作欄位分隔符(多個空格仍然作為一個分隔符),但是可以將分隔符從空格改為任何其它字元。

當 AWK 讀取輸入內容時,整條記錄被分配給變數 $0。每個欄位以欄位分隔符分開,被分配給變數 $1、$2、$3 等等。一行在本質上可以包含無數個欄位,通過欄位號來訪問每個欄位。

所以print $0 的意思是列印當前處理的整行數據,」
」表示換行。

設置文本中每一行後面有且只有一空行sed方法:

sed "/^$/d;G" express

sed相關的命令參數:d從模板塊(Pattern space)位置刪除行,詳細解釋見文章開始提供的鏈接。G獲得內存緩衝區的內容,並追加到當前模板塊文本的後面。『;』號:如果在一行中有多個命令,要用分號隔開。

相關解釋:/^$/d;表示遇到空行,則刪除,d命令執行後不會繼續執行下面的命令G,而是直接讀入下一行重新執行"/^$/d;G"進行處理。直到匹配到不是空行才執行G命令把hold space中的內容(此時為空)追加到文本的後面,然後默認輸出。

awk方法:

awk "!/^$/{printf("%s

",$0)}" express

關於awk知識點:使用模式:

通過包含一個必須匹配的模式,您可以選擇只對特定的記錄而不是所有的記錄進行操作。模式匹配的最簡單形式是搜索,其中要匹配的項目被包含在斜線 (/pattern/) 中。

相關解釋:

!/^$/即是不是空行的printf(",$0)表示輸出當前處理的整行字元串,輸出字元的格式」"%s

」表示輸出字元串,然後執行兩個換行即空一行。

在每行後面增加2行空行sed方法:

sed "/^$/d;G;G" express

sed相關的命令參數:d從模板塊(Pattern space)位置刪除行。G獲得內存緩衝區的內容,並追加到當前模板塊文本的後面。

相關解釋:sed "/^$/d;G;G" /^$/表示匹配到空行時進行處理,d表示刪除,即是遇到空行就刪除,然後讀取下一行處理,直到讀取到的不是空行為止才執行下面的G;G;獲得內存緩衝區的內容,並追加到當前模板塊文本的後面,這裡的內存緩衝區中的內容此時為空。

awk方法:

awk "!/^$/{printf("%s

",$0)}" express

相關解釋:awk "!/^$/{printf("%s

",$0)}"表示查找到不是空行的就進行輸出printf("%s

",$0),輸出$0表示當前處理的整行字元,"%s

"表示輸出字元串,三個
表示空兩行。

刪除所有偶數行sed方法:

sed "n;d" express

sed相關的命令參數:n讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令。-n, --quiet, --silent安靜模式,取消默認輸出。d從模式空間(Pattern space)位置刪除行。相關解釋:sed 『n;d』 執行n時會首先輸出當前處理行,然後讀取下一行,並使用d命令刪除。

awk方法:

awk "NR%2!=0{print $0}" express

awk相關的命令參數:NR表示awk開始執行程序後所讀取的數據行數

相關解釋:『NR%2!=2』表示不是偶數行

在匹配The的行前插入空行sed方法:

sed "/The/{x;p;x}" express

sed相關的命令參數: x交換pattern和hold spacep列印pattern space

相關解釋:sed "/The/{x;p;x}"第一個x首先交換,這時pattern space為空,hold space為匹配/xx/這一行的內容,交換後使用p輸出模式空間中的內容為空行,然後再換回來,保持pattern space為空,為下一次處理做準備。

awk方法:

awk "{if (/The/) printf("
%s
",$0); else print $0}" express

awk相關命令參數:條件語句awk中的條件語句是從C語言中借鑒過來的,可控制程序的流程。格式:{if (expression){statement; statement; ...}}

相關解釋:awk "{if (/The/) printf("
%s
",$0);表示匹配到The的行,就使用printf函數輸出$0表示整行字元串,輸出的格式為」
%s
」表示先換行再輸出,然後再換行,表示The之前空一行。

輸出行號,行號和正文間加冒號sed方法:

sed = express | sed "N;s/
/:/"

sed相關命令參數: N追加下一個輸入行到模式空間後面並在二者間嵌入一個「
」,改變當前行號碼。=列印當前行號s/re/string用string替代正則表達式re

sed = express 輸出行號和行的內容,行號和內容分兩行輸出sed "N;s/
/:/"N讀取下一行(行的內容)在兩行之間插入
,然後再使用s/re/string把
替換成「:"

awk方法:

awk "{printf("%d:%s
",NR,$0)}" express

NR表示awk開始執行程序後所讀取的數據行數.$0表示當前處理的整行數據printf("%d:%s
",NR,$0) 輸出,格式為:十進位有符號整數輸出NR行號 :當前處理的行所包含的字元串。

對文件中的所有非空行編號sed方法:

sed "/./=" express | sed "/./N;s/
/:/"

sed相關命令參數: s/re/string用string替代正則表達式reN追加下一個輸入行到模式空間後面並在二者間嵌入一個「
」,改變當前行號碼。=列印當前行號.匹配一個非換行符的字元相關解釋:"/./="表示第一個字元是非換行字元的輸出行號,sed "/./N;s/
/:/"中N讀取下一行(行的內容)並在兩行之間插入
,然後再使用s/re/string把
替換成「:」

awk方法:

awk "{if (/./) printf("%d:%s
",NR,$0);else print $0}" express

awk相關命令參數: NR表示awk開始執行程序後所讀取的數據行數

相關解釋:printf("%d:%s
",NR,$0) 輸出,格式為:十進位有符號整數 :當前處理的行所包含的字元串整個語句表示:如果不是空行,則調用printf函數以「數字:字元串+換行」的形式輸出當前處理行號了整行內容,否則,直接輸出當前處理的整行內容。

計算行號(模擬 「wc -l」)sed方法:

sed -n "$=" express

關於WC命令:wc就是word count(數字數)的縮寫,通常利用Linux的wc命令和其他命令結合來計算行和其他信息。在Linux下用wc進行計數。返迴文件的行數、字數、位元組數等。wc -m filename:顯示一個文件的字元數wc -l filename:顯示一個文件的行數wc -L filename:顯示一個文件中的最長行的長度wc -w filename:顯示一個文件的字數sed相關的命令參數:-n, --quiet, --silent安靜模式,取消默認輸出。$錨定行的結束 如:/sed$/匹配所有以sed結尾的行。=列印當前行號相關解釋:$=表示列印最後一行的行號,-n表示安靜模式,不會輸出其他行的相關內容

awk方法:

awk "END {print NR}" express

awk相關的知識點: BEGIN和END在awk 中兩個特別的表達式,BEGIN和END,這兩者都可用於pattern中,提供BEGIN和END的作用是給程序賦予初始狀態和在程序結束之後執行一些掃尾的工作。任何在BEGIN之後列出的操作(在{}內)將在awk開始掃描輸入之前執行,而END之後列出的操作將在掃描完全部的輸入之後執行。因此,通常使用BEGIN來顯示變數和預置(初始化)變數,使用END來輸出最終結果。所以awk "END {print NR}"也就是在讀取到最後一行之後,才輸出對於的行號,也就是輸出該文件的行數。

模擬dos2unix

關於dos2unix命令dos2unix命令用來將DOS格式的文本文件轉換成UNIX格式的(DOS/MAC to UNIX text file format converter)。DOS下的文本文件是以
作為斷行標誌的,表示成十六進位就是0D 0A。而Unix下的文本文件是以
作為斷行標誌的,表示成十六進位就是 0A。DOS格式的文本文件在Linux底下,用較低版本的vi打開時行尾會顯示^M,而且很多命令都無法很好的處理這種格式的文件,如果是個shell腳本,。而Unix格式的文本文件在Windows下用Notepad打開時會拼在一起顯示。因此產生了兩種格式文件相互轉換的需求,對應的將UNIX格式文本文件轉成成DOS格式的是unix2dos命令。所以實現dos2unix的關鍵就是把dos中多餘的
去掉。

sed方法:

sed "s/
//g" expressdos >expressdos1 模擬unix2dos:sed "s/$/
/" expressdos > expressdos1或sed "s/$/x0d/" expressdos >expressdos1

sed相關命令參數: s/re/string用string替代正則表達式re相關解釋:使用s/re/string替換多餘的
,然後默認輸出模式空間中的數據

awk方法:

awk "gsub(/
/,""){print $0}" express > express2

awk相關知識點: gsub(r,s,t)在字元串t中用字元串s和正則表達式r匹配的所有字元串。返回值是替換的個數。如果沒有給出t,默認是$0相關解釋:使用gsub把
替換成"",然後再輸出當前處理的整行字元串

將所有good改為bad並列印且只列印該行sed方法:

sed -n "s/good/bad/"p express

sed相關命令參數: s/re/string用string替代正則表達式re-n, --quiet, --silent安靜模式,取消默認輸出。p列印模式空間的行,通常 p 會與參數 sed -n 一起使用。相關解釋:使用安靜模式取消默認輸出,s/good/bad表示如果匹配到good,則替換為bad,並列印輸出。

awk方法:

awk "gsub("good","bad"){print $0}" express

相關解釋:使用gsub把good替換成bad,接著列印整行

將包含is的行的good改為bad並列印且只列印該行sed方法:

sed -n "/is/{/good/{s/good/bad/g;p}}" express

sed相關命令參數: -n安靜模式,取消默認輸出。g表示行內全面替換,當前處理行進行全局替換。

相關解釋:

-n使用安靜模式,/is/匹配包含is的行,/good/匹配包含is的行中包含good的行,s/good/bad/g,把改行所有的good都替換成bad,然後使用p輸出該行。

awk方法:

awk "{if ($0~/is/ && $0~/good/) {gsub(/good/,"bad"); print $0}}" express

相關解釋:$0~/is/表示使用第0個域匹配/is/正則表達式,第0個域保存的即是當前處理的整行數據。($0~/is/ && $0~/good/)就是如果當前處理的整行同時包含is和good的話就執行if裡面的語句。if裡面的語句使用gsub把匹配的good替換成bad,然後輸出當前行。

將不包含is的行的good改為bad並列印且只列印該行sed方法:

sed -n "/is/!{/good/{s/good/bad/g;p}}" express

sed相關命令參數: !表示後面的命令對所有沒有被選定的行發生作用。相關解釋:-n使用安靜模式,/is/匹配包含is的行,然後使用!取得沒有被匹配到的行進行操作,/good/表示從沒有被匹配到的行中匹配包含good的行,s/good/bad/g,把改行所有的good都替換成bad,然後使用p輸出該行。

awk方法:

awk "{if ($0!~/is/ && $0~/good/) {gsub(/good/,"bad"); print $0}}" express

相關解釋:$0!~/is/表示使用第0個域匹配/is/正則表達式,找出匹配不到的行繼續進行處理。第0個域保存的即是當前處理的整行數據。($0!~/is/ && $0~/good/)就是如果當前處理的整行不包含is和包含good的話就執行if裡面的語句。if裡面的語句使用gsub把匹配的good替換成bad,然後輸出當前行。

顯示文件中的前10行 (模擬「head」)

關於head命令:head是查看文件默認前10行

sed方法:

sed 10q express

相關解釋:q表示退出sed,10q表示處理到第10行的時候退出sed。

awk方法:

awk "{if (NR<11) print $0}" express

awk相關的命令參數: NR表示awk開始執行程序後所讀取的數據行數

在每5行後增加一空白行sed方法:

sed "n;n;n;n;G" express

sed相關命令參數: n讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令。G獲得內存緩衝區(hold space)的內容,並追加到當前模式空間文本的後面。

相關解釋:n;n;n;n;G的執行4個n命令讀取下一行,每次讀取之前都先輸出當前的處理行。然後把hold space(這時為空)中的內容追加到模式空間的後面,相當於增加一空白行。

awk方法:

awk "{if (NR%5!=0) print $0;else printf("%s

",$0)}" express

awk相關的命令參數: NR表示awk開始執行程序後所讀取的數據行數.相關解釋:如果讀取的數據行數不是5的倍數,則直接列印整行,如果是5的倍數,則調用printf("%s

",$0)函數列印整行和一個空行。

倒置所有行,第一行成為最後一行,依次類推(模擬「tac」)

關於tac命令:把文件內容反過來顯示,文件內容的最後一行先顯示,第一行最後顯示。

sed方法:

sed "1!G;h;$!d" express

sed相關方法: G獲得內存緩衝區的內容,並追加到當前模板塊文本的後面。h拷貝模板塊的內容到內存中的緩衝區。d從模板塊(Pattern space)位置刪除行。!表示後面的命令對所有沒有被選定的行發生作用。$錨定行的結束 如:/sed$/匹配所有以sed結尾的行。這裡表示文件最後一行。1表示文件第一行

相關解釋:第一行的時候1!G:在處理第一行的時候不把緩衝內容添加到 當前處理行的末尾(因為你處理第一行的時候,緩衝還為空呢)h:這個時候把第一行的內容(1)放到緩衝區$!d:因為不是最後一行,所以刪除,不列印出來第二行的時候1!G:此時1!G成立,把上一次保存的緩衝區內容(1)放到當前行(2)的末尾,第二行變成了(21)h:這個時候把第二行的內容(21)放到緩衝區$!d:因為不是最後一行,所以刪除,不列印出來第三行的時候1!G:因為是第三行,所以1!G成立,則把上一次(第二行)保存的緩衝區內容(21)放到當前行(3)的末尾,第二行變成了(321)h:這個時候把第三行的內容(321)放到緩衝區$!d:因為不是最後一行,所以刪除,不列印出來這樣直到處理到最後一行的時候:1!G:此時1!G成立,把上(n-1)一次保存的緩衝區內容([n-1]…321)放到當前行(n)的末尾,該行變成了(n…321)h:這個時候把第n行的內容(n…321)放到緩衝區$!d:因為是最後一行,所以不刪除,列印出第六行內容 n[n-1]…321

awk方法:

awk "{A[i++]=$0}END{for(j=i-1;j>=0;j--)print A[j]}" express

awk相關知識點: BEGIN和END在awk 中兩個特別的表達式,BEGIN和END,這兩者都可用於pattern中,提供BEGIN和END的作用是給程序賦予初始狀態和在程序結束之後執行一些掃尾的工作。任何在BEGIN之後列出的操作(在{}內)將在awk開始掃描輸入之前執行,而END之後列出的操作將在掃描完全部的輸入之後執行。因此,通常使用BEGIN來顯示變數和預置(初始化)變數,使用END來輸出最終結果。相關解釋:首先輸入每行字都執行A[i++]=$0,即是把所有行的內容保存到A[i]數組中。直到處理完所有的行之後,繼續質詢END中的內容:for(j=i-1;j>=0;j--)print A[j],這裡是吧A[i]中的元素倒序輸出,即是倒置所有的行。

顯示文件中的最後10行 (模擬「tail」)sed方法:

sed -e :a -e "$q;N;11,$D;ba" express

sed方法相關命令參數: -e直接在指令列模式上進行 sed 的動作編輯,允許多台編輯。:a表示建立一個標籤ab跳轉命令,這個命令是無條件跳轉ba表示跳轉到標籤a處q退出Sed。N追加下一個輸入行到模板塊後面並在二者間嵌入一個「
」,改變當前行號碼。D刪除模板塊的第一行。11表示文件第十一行相關解釋:首先創建一個a標籤,然後不斷執行這段代碼:$q;N;11,$D;ba,如果是最後一行則退出sed,否則繼續循環,N讀取下一行,讀取模式空間的第11行,如果是最後一行則刪除模式空間的第一行,繼續跳到標籤a處執行。

awk方法:

awk "{a[i++]=$0}END{if (i>10) for (j=i-10;j<i;j++) print a[j];else for (j=0;j<i;j++)print a[j]}" express

相關解釋:使用{a[i++]=$0}把每行字元串賦給a[i]數組,然後判斷數組大小是不是大於10 if (i>10),如果是則輸入最後10個元素,否則直接輸出所有的元素。

顯示文件中的最後2行(模擬「tail -2」命令)

關於tail命令:tail [ -r ] [ -n Number ] [ File ]tail 命令從指定點開始將 File 參數指定的文件寫到標準輸出。如果沒有指定文件,則會使用標準輸入。 Number 變數指定將多少單元寫入標準輸出。 Number 變數的值可以是正的或負的整數。如果值的前面有 +(加號),從文件開頭指定的單元數開始將文件寫到標準輸出。如果值的前面有 -(減號),則從文件末尾指定的單元數開始將文件寫到標準輸出。如果值前面沒有 +(加號)或 -(減號),那麼從文件末尾指定的單元號開始讀取文件。tail -2即是輸出最後兩行。

sed方法:

sed "$!N;$!D" express

sed相關命令參數: !表示後面的命令對所有沒有被選定的行發生作用。N追加下一個輸入行到模板塊後面並在二者間嵌入一個「
」,改變當前行號碼。D刪除模板塊的第一行。相關解釋:$!表示如果不是最後一行則執行N命令讀取下一行,$!D表示如果不是最後一行則刪除第一行。注意:執行D命令之後,pattern space 內不添加下一筆數據, 而將剩下的數據重新執行sedscript 。也就是直接再次執行$!N命令,讀入下一行。知道最後一行時就不執行D刪除命令,此時patten space中有最後兩行數據。

awk方法:

awk "{a[i++]=$0}END{if (i>2) for (j=i-2;j<i;j++) print a[j];else for (j=0;j<i;j++)print a[j]}" express

相關解釋:

a[i++]=$0命令保存所有行到a[i]數組中。處理完所有語句之後執行END里的內容。然後分兩種情況輸出:超過兩條語句的使用a[i]數組輸出最後兩行,沒有超過兩句的,直接使用a[i]輸出。

顯示文件中的最後一行(模擬「tail -1」)sed方法:

sed "N;D" express

相關解釋:N讀取下一行,接著使用D刪除第一行,此時patten space中只剩下後一行。注意:執行D命令之後,pattern space 內不添加下一筆數據, 而將剩下的數據重新執行sedscript 。也就是直接再次執行N命令,讀入下一行,然後刪除第一行。一直這樣循環,直到最後一行,列印輸出patten space中的內容,也就是最後一行的內容。

awk方法:

awk "END{print $0}" express

相關解釋: awk中處理完所有的語句後(這裡沒做處理),執行END里的內容,print $0,表示輸出最後一次處理的整行信息,即最後一行的內容。

顯示第9行sed方法:

sed -n "9p" express

sed相關命令參數: -n安靜模式,取消默認輸出。p列印模式空間的行,通常 p 會與參數 sed -n 一起使用9表示文件第9行

awk方法:

awk "{if (NR==9) print $0}" express

awk相關命令參數: NR表示awk開始執行程序後所讀取的數據行數

顯示包含50個或以上字元的行sed方法:

sed -n "/^.{50,}$/p" express

sed相關的命令參數: -n安靜模式,取消默認輸出。p列印模板塊的行。.匹配一個非換行符的字元相關解釋:"/^.{50}$/p" 表示匹配以非換行字元開始的50個以上的字元的行,然後使用p命令輸出。

awk方法:

awk "{if (length($0)>=50) print $0}" express

length(s)函數:返回s長度

顯示部分文本——從包含apple的行開始到最後一行結束sed方法:

sed -n "/apple/,$p" express

awk方法:

awk "BEGIN{p=1}{if ($0~/apple/ || p==0){p=0;print $0}}" express

相關解釋:在處理語句之前,先執行BEGIN裡面的語句,即讓p=1。然後使用($0~/apple/ || p==0)判斷正在處理的該行語句有沒有apple,如果有,則讓p=0,然後輸出該行,由於此時p==0,所以條件總是成立,會把接下來到最後的語句全部輸出。

顯示通篇文檔,除了從包含apple的行到包含google的行sed方法:

sed "/apple/,/google/d" express

相關解釋:/apple/,/google/d表示匹配從包含apple的行到包含google的行,然後使用d全部刪除。

awk方法:

awk "BEGIN{p=1}{if ($0!~/apple/ && p==1)print $0;else p=0;if ($0~/google/) p=1;}" express

相關解釋:首先在BEGIN中給p賦初值1,然後依次處理每一條語句。如果沒有匹配到apple並且p==1,則輸出改行;否則p=0,直到匹配到google為止,才讓p=1,繼續輸出。

推薦閱讀:

如何在終端中使用 Instagram | Linux 中國
如何反駁「Powershell 比 Linux 終端好得多」這種說法?
工業中為什麼很少採用 Linux 伺服器?
拒絕壟斷,從我做起。
如何在 Linux 系統中結束進程或是中止程序

TAG:Linux | 解析 |