Linux命令之sed

sed: stream editor
sed是面向字符流的,從文本文件中一次一行的讀取輸入,經過處理後,將結果發送到標準輸出端。
sed本身不會修改輸入文件本身,它只是改變了輸入文件的副本,並將結果輸出到標準輸出設備。

sed的使用有兩種方式:
1 命令行模式
sed [[address][,address]] command infile
一般用單引號將 address command 括起來。
2 腳本模式
sed -f script infile
-f後接的是腳本文件名

兩種方式其實是一樣的,只是將[[address][,address]] command部分單獨放在了腳本文件中。

sed 默認會自動輸出所有行,使用-n參數禁止自動輸出。

sed之行地址:
首先介紹命令行中的address。 sed是以行爲單位進行處理的。address選項提供了對於行的控制操作。行地址是每個命令可選的參數。sed命令可以指定零個,一個或兩個地址。每個地址都是一個描述模式,行號或者行尋址符號的正則表達式。

  • 如果沒有指定地址,那麼命令將應用於每一行
  • 如果只有一個地址,那麼命令應用於這個地址匹配的任意行
  • 如果指定了由逗號分隔的兩個地址,那麼命令應用於第一個地址的第一行和它後面的行,直到匹配第二個地址的行(包括該行)
  • 如果地址後面跟有感嘆號(!),那麼命令就應用於不匹配該地址的所有行

我們以刪除命令d來解釋尋址工作。

sed ‘d’ file
沒有指明地址,刪除所有行

sed ‘1d’ file
行號指明第一行,刪除第一行,行號是指由sed維護的內部行數.

sed ‘$d’ file
$爲行尋址符號,表示最後一行,即刪除最後一行

sed ‘/^$/d’ file
刪除空行。
注意,用正則表達式表示地址時,正則表達式必須封閉在斜槓(/)中

sed ‘/^TS/ , /^TE/ d’ file
刪除以TS開頭的行到以TE開頭的行之間的行,注意,如果以TS開頭到以TE開頭的行有多個,則都要刪除。例子如下:

/var/root # cat file                                                            
abbb                                                                            
baaa                                                                            
abbb                                                                            
baaa                                                                            
cccc      
/var/root # sed '/^a/,/^b/ d' file                                              
cccc                              

刪除以a開頭到以b開頭的行,有兩組,都被刪除了。符合模式匹配的行都被刪除了.

sed ‘50,$ d’ file
刪除50行到最後一行

sed ‘1,/^$/ d’ file
刪除從第一行知道第一個空行的所有行。

sed ‘/^TS/,/^TE/! d’ file
地址後加感嘆號,表示刪除在TS開頭和TE開頭的行之外的所有行。

保存和輸出:
可以將結果保存在單獨的文件中
sed ‘/^TS/,/^TE/! d’ file > outfile
sed -f script file > outfile
使用IO重定向,注意,輸入輸出文件不能是同一個。

多重指令:
對於同一個文件,指明多個指令,有3中方式可以實現:
1 用分號分隔指令
sed ‘s/MA//BB/; s/C/D/’ file
2 在每個指令前放置-e
sed -e ‘s/MA//BB/’ -e ‘s/C/D/’ file
3 使用Bourne Shell的分行指令工能。在輸入單引號後按Enter鍵,就會出現多行輸入的提示符(>)。
> sed ’
>s/MA//BB/
>s/C/D/’ list

分組命令
sed使用大括號{}將一個地址嵌套在另一個地址中,或者在相同的地址上應用多個命令
如果想指定行的範圍,然後在這個範圍內指定另一個地址,則可以嵌套地址。
/^TS/,/^TE/{
/^$/d
}
左大括號必須在行末,而且右大括號分身必須單獨佔一行。要確保在大括號之後沒有空格。

可以用大括號將編輯命令括起來對某個範圍的行應用多個命令:
/^TS/,/^TE/{
/^$/d
s/ps/qs/
}

基本sed命令:
sed命令集由25個命令組成。我們只介紹一些常用的命令。
替換
命令格式:
[address] s/pattern/replacement/flags
這裏修飾替換的標識flags是:
n : 1到512之間的一個數字,表示對文本模式中指定模式第n次出現的情況進行替換
g :對模式空間的所有出現的情況進行替換。默認情況下只有第一次出現的情況被替換
p: 打印模式空間的內容.只輸出替換的行
W file:將模式空間的內容寫到文件file

替換元字符:
replacement是一個字符串,用來替換與正則表達式匹配的內容。在replacement中,只用下列字符有特殊含義。
& : 用正則表達式匹配的內容替換
\n:匹配第n個子串,這個子串以前在pattern中用”(“和”)”指定
\: 當在替換部分包含&,\,和定界符時,可用\轉義他們。

1 用換行符替換逗號
column1,column2,column3,column4
s/,/\
/2
在反斜槓後面不允許有空格, 結果爲
column1,column2
column3,column4

輸入爲: on the UNIX Operating System
s/UNIX/Linux & Unix/
結果爲:
on the Linux Unix Unix Operating System
這個因爲&代表pattern串。如果要輸出&,需要轉義。
s/UNIX/Linux \& Unix/

刪除
前面講過

追加,插入和更改
追加[line-address]a\
text

插入[line-address]i\
text

更改[line-address]c\
text

插入命令將所提供的文本放置在模式空間的當前行之前,追加命令將文本放在當前行之後。更改命令用所提供的的文本取代模式空間的內容。

這些命令中的每一個都要求後面跟一個反斜槓用於轉義第一個行尾。

1)命令i在指定行前增加一個新行,命令a在指定行後附加一個新行
# echo “it is line 2”| sed ‘i\it is line 1’ //i之後爲右\符號
it is line 1
it is line 2

# echo “it is line 2”| sed ‘a\it is line 1’
it is line 2
it is line 1

2)對指定行前插入或附加多行
# cat dataline
line 1
line 2
line 3
# sed ‘1i\ //i前加數字,指定第幾行
> it is line 1\ //插入多行每行的開頭需加反斜線
>it is line 2’ dataline
it is line 1
it is line 2
line 1
line 2
line 3

# sed ‘1a\
> it is line one\
> it is line two’ dataline
line 1
it is line one
it is line two
line 2
line 3

3)修改行,機制同插入與附加
# sed ‘1c\it is line one’ dataline
it is line one
line 2
line 3

4)修改多行
cat file
line1
line2
line3
sed ‘1,2 c\line’ file
line
line3
可以看出,直接將line1和line2改成了line。
更改命令可以一次處理一個範圍的行。

插入命令和追加命令不影響模式空間的內容。
在sed執行插入命令時,插入的文本在當前行的前面輸出,模式空間不變。後續命令匹配新插入的字符串會失敗。

轉換
命令格式:
[address] y/abc/xyz
這個命令按位置將字符串abc中的每個字符替換成字符串xyz中相同位置的字符。

echo “abc” | sed ‘y/abc/xyz’
結果:xyz

如果前面的字符個數少於後面,則後面缺失的不替換
echo “abc” | sed ‘y/ab/xyz’
結果:xyc

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