linux之sed命令n,N,d,D,p,P,h,H,g,G,x解析

前言

sed執行模板 = sed ‘模式{命令1;命令2}’ 文件,即逐行讀入模式空間,執行命令,最後輸出打印出來。

sed的語法格式:

sed [option] 'pattern{sed-command1;sed-command2}' {input-file}

sed在正常情況下,將處理的行讀入模式空間(pattern space),腳本中的“sed-command(sed命令)”就一條接着一條進行處理,直到腳本執行完畢,然後該行被輸出,模式(pattern space)被清空。接着,在重複執行剛纔的動作,文件中的新的一行被讀入,直到文件處理完畢。

但是,由於種種原因,如用戶希望在某個條件下,腳本中的某個命令被執行或希望模式空間(pattern space)保留,以便下一次使用,這都有可能使sed在處理文件的時候,不按照正常的流程來進行處理,這時候就需要用sed高級命令來滿足需求。

p和P命令

p打印當前模式空間所有內容,追加到默認輸出之後;P打印當前模式空間開端至\n的內容,並追加到默認輸出之前。
Sed並不對每行末尾\n進行處理,但是對N命令追加的行間\n進行處理,因爲此時sed將兩行看做一行。

n和N命令

命令n:讀取下一行到pattern space。由於pattern space中有按照正常流程讀取的內容,使用n命令後,pattern space中又有了一行,此時,pattern space中有2行內容,但是先讀取的那一行不會被刪除;當n命令後,還有其他命令p的時候,此時打印出的結果是n命令讀取的那一行的內容。

看下圖,你就明白了。

新建文件,其內容如下

cat 1.txt

1

2

正常sed流程

使用n命令後,

N命令:將下一行添加到pattern space中。將當前讀入行和用N命令添加的下一行看成“一行”。

新建文件1.txt

cat 1.txt

1

2

正常sed流程

使用N命令後

=========================================================

n命令簡單來說就是提前讀取下一行,覆蓋模型空間前一行(並沒有刪除,因此依然打印至標準輸出),執行後續命令。然後再讀取新行,對新讀取的內容重頭執行sed。如果命令未執行成功(並非跳過:前端條件不匹配),則放棄之後的任何命令,並對新讀取的內容,重頭執行sed。

例子:從aaa文件中取出偶數行

[root@localhost ~]# cat a.txt
This is 1   
This is 2   
This is 3   
This is 4   
This is 5
[root@localhost ~]# sed –n ‘n;p’ a.txt
This is 2   
This is 4   

讀取This is 1,執行n命令,此時模式空間爲This is 2,執行p,打印模式空間內容This is 2,之後讀取This is 3,執行n命令,此時模式空間爲This is 4,執行p,打印模式空間內容This is 4,之後讀取This is 5,執行n命令,因爲沒有了,所以退出,並放棄p命令。因此,最終打印出來的就是偶數行。

N 追加下一行到當前行,把兩行看作一行,但是\n換行符還在。如果命令未執行成功,則放棄後面的命令,讀取下一行再執行sed。
sed命令n,N,d,D,p,P,h,H,g,G,x解析

使用N命令後
sed命令n,N,d,D,p,P,h,H,g,G,x解析

N命令簡單來說就是追加下一行到模式空間,同時將兩行看做一行,但是兩行之間依然含有\n換行符,然後執行後續命令,然後再讀取新行,對新讀取的內容重頭執行sed。此時,新讀取的行會覆蓋之前的行(之前的兩行已經合併爲一行)。如果命令未執行成功(並非跳過:前端條件不匹配),則放棄之後任何命令,並對新讀取的內容,重頭執行sed。

#例子:從aaa文件中讀取奇數行
[root@localhost ~]# sed –n ‘N;P’ a.txt   -----因爲讀取第5行時,執行N,發現沒有第6行,不滿足,就退出,放棄P命令
This is 1   
This is 3   
[root@localhost ~]# sed –n ‘$!N;P’ a.txt   
This is 1   
This is 3   
This is 5
[root@localhost ~]#

註釋中1代表This is 1 ,2代表This is 2 以此類推
註釋:讀取1,$!條件滿足(不是尾行),執行N命令,得出1\n2,執>行P,打印得1,讀取3,$!條件滿足(不是尾行),執行N命令,得出>3\n4,執行P,打印得3,讀取5,$!條件不滿足,跳過N,執行P,打印得5

d和D命令

d命令是刪除當前模式空間內容(不再傳至標準輸出),並放棄之後的命令,並對新讀取的內容,重頭執行sed。

[root@localhost ~]# sed ‘n;d’ a.txt 
This is 1   
This is 3   
This is 5
[root@localhost ~]#

註釋:讀取1,執行n,得出2,執行d,刪除2,得空,以此類推,讀取3,執行n,得出4,執行d,刪除4,得空,但是讀取5時,因爲n無法執行,所以d不執行。因無-n參數,故輸出1\n3\n5

D命令是刪除當前模式空間開端至\n的內容(不在傳至標準輸出),放棄之後的命令,但是對剩餘模式空間重新執行sed。

Sed 'N;D' aaa           
This is 5   

註釋:讀取1,執行N,得出1\n2,執行D,得出2,執行N,得出2\n3,執行D,得出3,依此類推,得出5,執行N,條件失敗退出,因無-n參數,故輸出5

y命令:對之前匹配的字符逐個替換

[root@localhost ~]# awk '{print $0"h"}' a.txt | sed ‘y/his/HIS/’
THIS IS 1H
THIS IS 2H
THIS IS 3H
THIS IS 4H
THIS IS 5H
[root@localhost ~]#sed 's/\b[a-z]\b/\u&/g' ddd   
This is A and A is 1   
This is B and B is 2   
This is C and C is 3   
This is D and D is 4   
This is E and E is 5    
#此外,如果需要對某個字符串進行大小寫轉換,則可使用如下方法    

h命令,H命令,g命令,G命令

h命令是將當前模式空間中內容覆蓋至緩存區,H命令是將當前模式空間中的內容追加至緩存區
g命令是將當前緩存區中內容覆蓋至模式空間,G命令是將當前緩存區中的內容追加至模式空間

[root@wmsvmpc ~]# sed –e ‘/101/h’ –e ‘$G’ cs1.txt 
PBCSPOFT0101    6
PBCSPOFT0102    0
PBCSPOFT0103    8
PB\CSPOFT0104   0
PBCSPOFT0101    6
[root@wmsvmpc ~]#

在sed處理文件的時候,每一行都被保存在一個叫模式空間的臨時緩衝區中,除非行被刪除或者輸出被取消,否則所有被處理的行都將打印在屏幕上。接着模式空間被清空,並存入新的一行等待處理。
在上面的例子裏,匹配test的行被找到後,將存入模式空間,h命令將其複製並存入一個稱爲保持緩存區的特殊緩衝區內。第二條語句的意思是,當到達最後一行後,G命令取出保持緩衝區的行,然後把它放回模式空間中,然後被打印(也就末尾)。

[root@wmsvmpc ~]# sed –e ‘/101/h’ –e ‘/102/G’ cs1.txt   
PBCSPOFT0101    6
PBCSPOFT0102    0
PBCSPOFT0101    6
PBCSPOFT0103    8
PB\CSPOFT0104    0
#追加到包含102的行的下一行

將ddd文件中數字和字母互換,並將字母大寫

cat ddd.sed
h  
{  
s/.*is \(.*\) and .*/\1/  
y/abcde/ABCDE/
G  
s/\(.*\)\n\(.*is \).*\(and \).*\(is \)\(.*\)/\2\5 \3\5 \4\1/  
}  

sed –f ddd.sed ddd  
This is 1 and 1 is A  
This is 2 and 2 is B  
This is 3 and 3 is C  
This is 4 and 4 is D  
This is 5 and 5 is E    

註釋:讀取1,執行h,複製到緩存區,執行s,模式空間得到匹配到的字母a,然後執行y,將a轉成A,執行G,追加緩存區內容到模式空間,得
A\nThis is a and a is 1;執行s,重新排列,得出This is 1 and 1 is A;以此類推,得出結果。
這裏需要注意的是匹配的內容中,空格一定要處理好,空格處理不對,會造成第二次s匹配錯誤,無法執行重新排列或排列錯誤

x命令

x命令是將當前緩存區和模式空間內容互換

[root@wmsvmpc ~]# sed –e ‘/101/h’ –e ‘/102/x’ cs1.txt   
PBCSPOFT0101    6
PBCSPOFT0101    6
PBCSPOFT0103    8
PB\CSPOFT0104   0
#互換模式空間和保持緩衝區的內容。也就是把包含101與102的行互換。應該是替換.

[root@wmsvmpc ~]#  echo –e "a\nb\nc\nd\n"|sed –nr 'H;${x;s/\n//g;p}'
abcd

r:use extended regular expressions in the script,使用功能更強大的正則表達式。
${} 表示處理到文件最後一行時執行{}中的命令,x把之前存入緩存區的數據按先入先出的順序放入模式空間,然後做替換,最後打印

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章