前言
我在參考其它多個Blog中發現,有些Blog中sed的功能介紹和實際有出入,這可能和版本有關系,正如sed文檔中所說“might change in future versions”,所以本文sed是以4.2.1為例。如果以后sed更新版本了,有可能會不一樣。
好記性不如爛筆頭!
sed的工作原理
sed維護著兩個數據的緩沖空間,一個是模式空間(pattern space)和另外一個保留空間(hold space),在初始環境下都為空。
sed是一個流編輯器,它會循環的從輸入流中讀取每一行,直到讀完整個文件。具體如下:
首先,它會從輸入流中讀取一行(如果剛開始就是第一行),移除行尾的換行符,放置于模式空間當中,接著一條條的運行命令(命令可以有多個并且是按序執行,如果某個命令地址定界了一個行號,只有滿足該行號才會執行命令,如“1d”,意思是如果是第一行則刪除模式空間內的內容)。
當命令運行完畢之后,除非使用了 -n 選項,否則會把模式空間的內容加上之前刪過的換行符并打印到輸出。然后讀入下行,執行下一個循環。如果沒有使諸如‘D’的特殊命令,那會在兩個循環之間清空模式空間,但不會清空保留空間。
意譯自http://www.gnu.org/software/sed/manual/sed.html中 3.1 How sed Works
流程圖如下
注:上面只是標準流程,某些特殊命令會有自己的流程
n N的說明
范例文件1
[root@CZ tmp]# cat 1 1 2 3 4 5 6 7 8 9 10 11
n:打印當前模式空間內容,然后讀取下一行并替代當前模式空間的內容。如果讀取不到下一行sed則會不運行之后的命令
我們通過以下命令了解一下n
[root@CZ tmp]# sed 'n;d' 1 1 3 5 7 9 11
上面命令過程是這樣
-
先讀取第一行進模式空間(以后簡稱為1)
-
執行命令n,過程如下
-
打印1到輸出
-
讀取2并覆蓋到模式空間
-
執行命令d,過程如下
-
刪除模式空間的內容
-
立即執行下一循環(d命令在運行后會直接執行下一循環,所以它并不會執行之后的命令和打印模式空間,具體d介紹會留在下次分享)
-
按照上面的流程循環執行…….直到讀取到11(最后一行),11的具體過程如下
-
讀取11進模式空間
-
運行命令n,不過讀取不到下一行
-
因為讀不到,所以sed退出所有的命令,也就是說它不會執行命令d
-
加回換行符并打印模式空間的內容到輸出,當前模式空間內容為11,所以輸出11
-
已經是文件尾,sed結束運行。
N:讀取下一行并且附加到當前模式空間內,如果讀取不到下一行sed則會不運行之后的命令
我們通過以下命令了解一下N
[root@CZ tmp]# sed 'N;a---' 1 1 2 --- 3 4 --- 5 6 --- 7 8 --- 9 10 --- 11
上面命令過程是這樣
-
讀取1進模式空間
-
執行命令N
-
讀取2并附加到模式空間,當前模式空間內容為“1\n2”
-
執行命令a—
-
在模式空間后附加一行‘—’當前模式空間內容為“1\n2\n—"
-
打印模式空間內容
-
循環執行直到讀取11進模式空間,11的具體過程如下
-
讀取11進模式空間
-
執行命令N,不過讀取不到下一行
-
因為讀不到,所以sed退出所有的命令,也就是說它不會執行命令a
-
加回換行符并打印模式空間的內容到輸出,當前模式空間內容為11,所以輸出11
-
已經是文件尾,sed結束運行。
尾言:
n N經常和d D一起用,不過D有點復雜,所以留在下次分享,不過我先劇透一下,D會刪除模式空間內第一行,并且如果模式空間內容不為空,它會循環執行前面命令。直到為空才會執行下一循環。
參考
http://www.gnu.org/software/sed/manual/sed.html
上面是官方文檔,如果下面和上面沖突,請以上面為準,下面blog有些內容和我理解有出入,請自行判斷。
http://www.cnblogs.com/fhefh/archive/2011/11/14/2248942.html
http://www.cnblogs.com/theCambrian/p/3606214.html
http://blog.csdn.net/yanquan345/article/details/19613443
http://www.cnblogs.com/fhefh/archive/2011/11/22/2259097.html
原創文章,作者:Unknown,如若轉載,請注明出處:http://www.www58058.com/5900