Linux應用之sed刪除空行

一、sed編輯器介紹

sed編輯器被稱作流編輯器(stream editor),和普通的交互式文本編輯器恰好相反。在交互式文本編輯器中(比如vim),你可以用鍵盤命令來交互式插入、刪除或替換數據中的文本。流編輯器則會在編輯器處理數據之前基於預先提供的一組規則來編輯數據流。
sed編輯器可以根據命令來處理數據流中的數據,這些命令要麼從命令行中輸入,要麼存儲在一個命令文本文件中(即腳本文件)。sed編輯器會執行下列操作:

  • 依次從輸入中讀取一行數據
  • 根據所提供的編輯器命令匹配數據
  • 按照命令修改流中的數據
  • 將新的輸數據輸出到STDOUT

在流編輯器將所有命令與一行數據匹配完畢後,它會讀取下一行數據並重復這個過程,直至處理完所有數據後終止。
sed命令的格式如下

sed options script file

二、sed刪除空白行

說明:在使用之前假設讀者有基本的正則知識,如果沒有,請自行學習

1. 刪除連續的空白行

如果我們的文本各行之間有不定數量的空白行,閱讀起來頗有些費力,且不美觀,我們希望各行之間間隔是固定的,比如僅有一行空白行的間隔,我們可以用到下面腳本:

/./ , /^$/!d

區間/./到/^$/的開始抵制會匹配任何含有至少一個字符的行,區間的結束地址會匹配一個空行,在這個區間的行不會被刪除。
實例

~$ cat example1
Such stories set us thinking, 

wondering what we should do under similar circumstances. 


What events, what experiences, 

what associations should we crowd into those last hours as mortal beings, 


what regrets?
~$ sed '/./,/^$/!d' example1
Such stories set us thinking, 

wondering what we should do under similar circumstances. 

What events, what experiences, 

what associations should we crowd into those last hours as mortal beings, 

what regrets?
~$

原來不規則的空白行變得均勻了。該示例中最後一行之後無內容,如果最後一行文字之後還有空白行,處理之後一會顯示一行空白行。

2. 刪除開頭的空白行

如果一段文本中開頭有多行空白,顯然會給閱讀帶來不便。刪除開頭的空白行與上面思路比較相似,我們可以用到下面腳本:

/./ , $!d

這個腳本將會對從有字符的行開始,一直到結束,這樣一個區間的內容都不會被刪除,也就是第一行正式內容之前的空白都會被刪除。
實例

~$ cat example2



Such stories set us thinking, 

wondering what we should do under similar circumstances. 
What events, what experiences, 
what associations should we crowd into those last hours as mortal beings, 
what regrets?
~$ sed '/./, $!d' example2
Such stories set us thinking, 

wondering what we should do under similar circumstances. 
What events, what experiences, 
what associations should we crowd into those last hours as mortal beings, 
what regrets?
~$

3. 刪除結尾的空白行

刪除連續的空白行中我們提到,對最後一行的處理也會包含一行空白行,也許這並不是我們想要的結果,我們希望最後一行不含空白行,我們可以用到下面腳本:

sed ‘{
:start
/^\n*$/{$d; N; b start}
}’

這段腳本可能稍微顯得有些複雜,在正常腳本的花括號中還有花括號,這允許你在整個命令腳本中將一些命令分組,該分組命令會被應用到指定的地址上。這裏用到了分支標籤b,可以實現跳轉,就像C語言中的循環。其含義就是如果找到了一行它僅有一個換行符,而且還是最後一行,那麼就刪除它,否則會繼續往後匹配。
實例

~$ cat example3
Such stories set us thinking, 

wondering what we should do under similar circumstances. 

What events, what experiences, 
what associations should we crowd into those last hours as mortal beings, 
what regrets?

~$ sed '{
:start
/^\n*$/{$d; N; b start}
}' example3
Such stories set us thinking, 

wondering what we should do under similar circumstances. 

What events, what experiences, 
what associations should we crowd into those last hours as mortal beings, 
what regrets?
~$

4. 刪除HTML標籤

應用中我們不少會從命令行去get一些網頁信息,其中包含了大量的html標籤信息,不利於我們獲取其中的主要信息,我們需要將其格式化爲普通文本,我們可以用到下面腳本:

s/ < [^>]*>//g ; /^$/d
**實例**
~$ cat example4
<html>
<head>
<title>This is the page</title>
</head>
<body>
<p>
This is the first line in the web page
This should provide some useful
information to use in our sed script
</p>
</body>
</html>
~$ sed -e 's/<[^>]*>//g ; /^$/d' data.txt
This is the page
This is the first line in the web page
This should provide some useful
information to use in our sed script
~$

說明:example4中的內容每一行之後立即換行,不含任何空格或者tab,讀者可以嘗試,在一些標籤後面加一些空格或者tab,得到的內容將會不一樣。

我們留心會發現,這裏的所有內容都是五縮進的,然而我們標準的html結構中通常是包含各種縮進關係的,比如下面的例子

~$ cat example5
<html>
	<head>
		<title>This is the page</title>
	</head>
		<body>
		<p>
		This is the first line in the web page
		This should provide some useful
		information to use in our sed script
		</p>
	</body>
</html>
~$ sed -e 's/<[^>]*>//g ; /^$/d' example5
	
		This is the page
	
		
		
		This is the first line in the web page
		This should provide some useful
		information to use in our sed script
		
	
~$

標籤都刪掉了,但是空行卻任然存在,爲什麼?我們將上述輸出保存,然後使用cat -t看看裏面的具體內容:

~$ sed -e 's/<[^>]*>//g ; /^$/d' data.txt > test
~$ cat -t test 
^I
^I^IThis is the page
^I
^I^I
^I^I
^I^IThis is the first line in the web page
^I^IThis should provide some useful
^I^Iinformation to use in our sed script
^I^I
^I
~$

可以看到,文本中的每個空行是實際上都有一個不可打印字符^I,它表示一個TAB,他在執行正則匹配/^$/d時 ,二則並不匹配,所以刪除空行操作並未執行。所以需要對該規則進行修改:

s/ < [^>]*>//g ; /^ [[:space:]]*$/d
區別在於空白行匹配中間增加了[[:space]]*,[[:space]]表示任意空白字符,包括空格、製表符、NL、FF、VT和CR。執行效果如下:
~$ sed -e 's/<[^>]*>//g ; /^[[:space:]]*$/d' example5
		This is the page
		This is the first line in the web page
		This should provide some useful
		information to use in our sed script
~$

可以看到,空行都刪除完了,但是每行之間任然有一部分空白,我們可以在上面的基礎上再次處理從而是刪掉該部分空白,修改規則如下

s/ < [^>]*>//g ; /^ [[:space:]]*$/d ; s/^[[:space:]]*$//g
我們對每一行開始的空格或者TAB進行匹配替換,從而達到刪除的效果:
~$ sed -e 's/<[^>]*>//g ; /^[[:space:]]*$/d; s/^[[:space:]]*//g' example5
This is the page
This is the first line in the web page
This should provide some useful
information to use in our sed script
~$

現在效果好多了,你可以將輸出重定向到你指定的文件中去。

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