sed 高級用法(1) 之 n N

前言

我在參考其它多個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

流程圖如下

sed 工作原理.jpg

注:上面只是標準流程,某些特殊命令會有自己的流程


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. 先讀取第一行進模式空間(以后簡稱為1)

  2. 執行命令n,過程如下

    1. 打印1到輸出

    2. 讀取2并覆蓋到模式空間

  3. 執行命令d,過程如下

    1. 刪除模式空間的內容

    2. 立即執行下一循環(d命令在運行后會直接執行下一循環,所以它并不會執行之后的命令和打印模式空間,具體d介紹會留在下次分享)

  4. 按照上面的流程循環執行…….直到讀取到11(最后一行),11的具體過程如下

    1. 讀取11進模式空間

    2. 運行命令n,不過讀取不到下一行

    3. 因為讀不到,所以sed退出所有的命令,也就是說它不會執行命令d

    4. 加回換行符并打印模式空間的內容到輸出,當前模式空間內容為11,所以輸出11

  5. 已經是文件尾,sed結束運行。 

 

N:讀取下一行并且附加到當前模式空間內,如果讀取不到下一行sed則會不運行之后的命令

我們通過以下命令了解一下N

[root@CZ tmp]# sed 'N;a---' 1
1
2
---
3
4
---
5
6
---
7
8
---
9
10
---
11

上面命令過程是這樣

  1. 讀取1進模式空間

  2. 執行命令N

    1. 讀取2并附加到模式空間,當前模式空間內容為“1\n2”

  3. 執行命令a—

    1. 在模式空間后附加一行‘—’當前模式空間內容為“1\n2\n—"

  4. 打印模式空間內容

  5. 循環執行直到讀取11進模式空間,11的具體過程如下

    1. 讀取11進模式空間

    2. 執行命令N,不過讀取不到下一行

    3. 因為讀不到,所以sed退出所有的命令,也就是說它不會執行命令a

    4. 加回換行符并打印模式空間的內容到輸出,當前模式空間內容為11,所以輸出11

  6. 已經是文件尾,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

(0)
UnknownUnknown
上一篇 2015-07-03 10:32
下一篇 2015-07-03 10:34

相關推薦

  • 網絡文件系統–NFS

        網絡文件系統(英語:Network File System,縮寫為NFS)是一種分布式文件系統協議,最初由Sun Microsystems公司開發,并于1984年發布。其功能旨在允許客戶端主機可以像訪問本地存儲一樣通過網絡訪問服務器端文件。     NFS和其他許多協議一…

    Linux干貨 2017-08-14
  • linux下vim命令詳解

    如果沒有安裝vim就請使用:sudo apt-get install vim 一個完整的.vimrc配置信息如下所示: set nocompatible set nummber filetype on set history=1000 set background=dark syntax on set autoindent set mouse=a set s…

    Linux干貨 2016-08-12
  • 磁盤分區管理之磁盤基礎知識1

    1、磁盤基礎知識 1.1 磁頭 磁頭是利用氣流漂浮在盤片上,并沒有接觸到盤片,因而可以在各軌間高速來回移動,但如果磁頭距離盤片太高,讀取的信號就會太弱;太低又會磨到盤片表面,所以盤片表面必須相當光滑平整,任何異物和塵埃均會使得磁頭摩擦到表面而造成數據永久性損壞。 硬盤讀寫磁頭為了能在磁盤表面高速來回移動讀取數據,則需漂浮在磁盤表面上,但是不能接觸,接觸就會造…

    Linux干貨 2016-09-07
  • 魔術方法

    魔術方法 屬性 含義 __name__ 類、函數、方法等的名字 __module__ 類定義所在的模塊名 __class__ 對象或類所屬的類 __bases__ 類的基類的元組,舒徐為他們在基類列表中出現的順序 __doc__ 類、函數的文檔字符串,如果沒有定義則為None __mro__ 類的mro,class.mro()返回的結果保存在__mro__中…

    Linux干貨 2017-11-21
  • 利用 yum 查找某個命令屬于哪個包

    當我們在安裝一個不熟悉的命令是,會遇到個問題:Error: Nothing to do 而你又不知道該命令的是屬于哪個rom包,莫慌~我們可以借助一個叫yum的基于rpm的軟件包管理器。 以 dig 這個命令為例,當我安裝它時會出現如下情況  [root@localhost ~]# yum install dig  Loaded plug…

    Linux干貨 2016-03-27
欧美性久久久久