歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> sed 高級用法

sed 高級用法

日期:2017/3/1 9:39:34   编辑:Linux編程

首先,應該明白模式空間的定義。模式空間就是讀入行所在的緩存,sed對文本行進行的處理都是在這個緩存中進行的。這對接下來的學習是有幫助的。

在正常情況下,sed將待處理的行讀入模式空間,腳本中的命令就一條接著一條的對該行進行處理,直到腳本執行完畢,然後該行被輸出,模式空間請空;然後重復剛才的動作,文件中的新的一行被讀入,直到文件處理完備。

但是,各種各樣的原因,比如用戶希望在某個條件下腳本中的某個命令被執行,或者希望模式空間得到保留以便下一次的處理,都有可能使得sed在處理文件的時候不按照正常的流程來進行。這個時候,sed設置了一些高級命令來滿足用戶的要求。

在sed命令中引入shell變量 http://www.linuxidc.com/Linux/2014-03/97896.htm

Linux下Shell編程——sed命令基本用法 http://www.linuxidc.com/Linux/2013-06/85526.htm

Unix文本處理工具之sed http://www.linuxidc.com/Linux/2013-08/89315.htm

總的來說,這些命令可以劃分為以下三類:
1. N、D、P:處理多行模式空間的問題;
2. H、h、G、g、x:將模式空間的內容放入存儲空間以便接下來的編輯;
3. :、b、t:在腳本中實現分支與條件結構。
多行模式空間的處理:
由於正則表達式是面向行的,因此,如若某個詞組一不分位於某行的結尾,另外一部分又在下一行的開始,這個時候用grep等命令來處理就相當的困難。然而,借助於sed的多行命令N、D、P,卻可以輕易地完成這個任務。
多行Next(N)命令是相對於next(n)命令的,後者將模式空間中的內容輸出,然後把下一行讀入模式空間,但是腳本並不會轉移到開始而是從當前的n 命令之後開始執行;而前者則保存原來模式空間中的內容,再把新的一行讀入,兩者之間依靠一個換行符"\n"來分隔。在N命令執行後,控制流將繼續用N命令以後的命令對模式空間進行處理。
值得注意的是,在多行模式中,特殊字符"^"和"$"匹配的是模式空間的最開始與最末尾,而不是內嵌"\n"的開始與末尾。
例1:
$ cat expl.1
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
現在要將"Owner and Operator Guide"替換為"Installation Guide":
$ sed '/Operator$/{
> N
> s/Owner and Operator\nGuide/Installation Guide\
> /
> }' expl.1
在上面的例子中要注意的是,行與行之間存在內嵌的換行符;另外在用於替代的內容中要插入換行符的話,要用如上的"\"的轉義。
再看一個例子:
例2:
$ cat expl.2
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.

Look in the Owner and Operator Guide shipped with your system.

Two manuals are provided including the Owner and
Operator Guide and the User Guide.

The Owner and Operator Guide is shipped with your system.
$ sed 's/Owner and Operator Guide/Installation Guide/
> /Owner/{
> N
> s/ *\n/ /
> s/Owner and Operator Guide */Installation Guide\
> /
}' expl.2
結果得到:
Consult Section 3.1 in the Installation Guide
for a description of the tape drives
available on your system.

Look in the Installation Guide shipped with your system.

Two manuals are provided including the Installation Guide
and the User Guide.

The Installation Guide is shipped with your system.
看上去sed命令中作了兩次替換是多余的。實際上,如果去掉第一次替換,再運行腳本,就會發現輸出存在兩個問題。一個是結果中最後一行不會被替換(在某些版本的sed中甚至不會被輸出)。這是因為最後一行匹配了"Owner",執行N命令,但是已經到了文件末尾,某些版本就會直接打印這行再退出,而另外一些版本則是不作出打印立即退出。對於這個問題可以通過命令"$!N"來解決。這表示N命令對最後一行不起作用。另外一個問題是"look manuals"一段被拆為兩行,而且與下一段的空行被刪除了。這是因為內嵌的換行符被替換的結果。因此,sed中做兩次替換一點也不是多余的。
例3:
$ cat expl.3
<para>

This is a test paragraph in Interleaf style ASCII. Another line
in a paragraph. Yet another.

<Figure Begin>

v.1111111111111111111111100000000000000000001111111111111000000
100001000100100010001000001000000000000000000000000000000000000
000000

<Figure End>

<para>

More lines of text to be found after the figure.
These lines should print.
我們的sed命令是這樣的:
$ sed '/<para>{
> N
> c\
> .LP
> }
> /<Figure Begin>/,/<Figure End>/{
> w fig.interleaf
> /<Figure End>/i\
> .FG\
> <insert figure here>\
> .FE
> d
> }
> /^$/d' expl.3
運行後得到的結果是:
.LP
This is a test paragraph in Interleaf style ASCII. Another line
in a paragraph. Yet another.
.FG
<insert figure here>
.FE
.LP
More lines of text to e found after the figure.
These lines should print.
而<Figure Begin>與<Figure End>之間的內容則寫入文件"fig.interleaf"。值得注意的是命令"d"並不會影響命令i插入的內容。
命令"d"作用是刪除模式空間的內容,然後讀入新的行,sed腳本從頭再次開始執行。而命令"D"的不同之處在於它刪除的是直到第一個內嵌換行符為止的模式空間的一部分,但是不會讀入新的行,腳本將回到開始對剩下內容進行處理。
例4:
$ cat expl.4
This line is followed by 1 blank line.

This line is followed by 2 blank line.


This line is followed by 3 blank line.

This line is followed by 4 blank line.

This is the end.

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-09/106961p2.htm

Copyright © Linux教程網 All Rights Reserved