天天看點

linux指令總結:sed

說明:

sed用于過濾和轉換文本的流編輯器

可以采用正則比對,對文本進行插入删除修改等操作

Sed處理的時候,一次處理一行,每一次把目前處理的存放在臨時緩沖區,處理完後輸出緩沖區内容到螢幕,然後把下一行讀入緩沖區,如此重複,直到處理完最後一行。

用法:

sed [OPTION] ... {script-only-if-no-other-script} [input-file] ...

sed [選項] ... [動作] [檔案]

參數:

-n 安靜模式,取消預設輸出

-e 直接在指令列上進行sed動作編輯

-f 讀取腳本檔案内sed指令處理檔案

-r sed動作支援延伸的正則表達(預設隻是基礎正則)

-i 直接修改檔案内容(實驗時慎用系統檔案)

-u 從輸入檔案加載少量的資料并重新整理更多的輸出緩沖區

--help 顯示幫助資訊并退出

--version  輸出版本資訊并退出

指令:

:label     是b和t指令的标簽,用來實作跳轉處理,名字可以随便取(label)

=     列印目前行号碼

a\    追加,在目前行的下一行追加文本

i\    插入,在目前行的上一行插入文本

q    退出,與Q一樣

b label    分行到标簽,如果标簽被省略,則分支到腳本的末尾。

t label    如果從上一次做了一個成功的替代,輸入行被讀取,并且從最後一個t或T指令,然後分支到标簽,如果省略則分支到末尾。

T label    如果沒有s///從上一次成功替換輸入行被讀取,并且從最後一個t或T指令,然後分支到标簽。如果省略則分支到末尾。

c \    用所有嵌入的文本替換所選行,換行符前面加反斜杠。

d    删除選擇的行

D    删除模版快的第一行

h H    複制或追加模版塊的内容到緩沖區

g G    擷取記憶體緩存區的内容,并替換或追加到目前模版塊文本

x    交換保留和模式空間的内容

l    以視覺上明确的形式列出目前行

n N  将下一行輸入讀取或附加到模式空間中

p    列印目前模版塊的行

P    列印莫闆塊的第一行

s/// 替換比對字元,可以使用正則

w    将目前模式空間寫入檔案

W    将目前模式空間的第一行寫入檔案

!   表示後面的指令對所有沒有被標明的行發生作用 

#    把注釋擴充到下一個換行符以前

sed替換标記:

g   表示行内全面替換 

p   表示列印行 

w   表示把行寫入一個檔案 

x   表示交換莫闆塊中的文本和緩沖區中的文本 

y   表示把一個字元翻譯成另外的字元 

\1  子串比對标記 

&   已比對字元串标記

sed 元字元集 :

^     比對行開始

$   比對行結束 

.   比對一個非換行符的任意字元

*   比對0個或多個字元比對所有子產品是一個或多個空格後緊跟sed的行 

[]  比對一個指定範圍内的字元 

[^] 比對一個不再指定範圍内的字元 

\(..\) 比對子串,儲存比對的字元,如 s/\(love\)able/\1rs loveable被替換成lovers 

&    儲存搜尋字元用來替換其他字元,如s/love/**&**/ love這成**love** 

\<   比對單詞的開始,如 /\<love/比對包含以love開頭的單詞行 

\>   比對單詞的結束,如/love\>/比對包含以love結尾的單詞的行 

x\{m\}   重複字元x,m次,如 /0{5\}/比對包含5個0的行 

x\{m,\}  重複字元x,至少m次,如 /0\{5,\}/比對至少有5個0的行 

x\{m,n\} 重複字元x ,至少m次,不多于n次,如 /0\{5,10\}/比對5~10個0的行

執行個體:

替換操作 :s指令 

替換文本中的字元串

<code>[root@zxq ~]</code><code># sed 's/aa/99/' aa.txt </code>

<code>99  123  345 aa bb cc </code><code>dd</code> <code>bb ee</code>

<code>bb 123 333 444 333 222 bb</code>

-n 選項和p選項一起使用表示隻列印發生變化的行

<code>[root@zxq ~]</code><code># sed -n 's/aa/www.baidu.com/p' aa.txt </code>

<code>www.baidu.com  123  345 aa bb cc </code><code>dd</code> <code>bb ee</code>

直接編輯檔案選項-i,會比對檔案中每一行比對的内容

<code>[root@zxq ~]</code><code>#sed -i 's/aa/888/g' aa.txt   #全面替換标記g</code>

<code>[root@zxq ~]</code><code># cat aa.txt </code>

<code>888  123  345 888 bb cc </code><code>dd</code> <code>bb ee</code>

當需要從第N出比對開始替換時,可以使用/Ng:

<code>[root@zxq ~]</code><code># echo ababababababab | sed 's/ab/AB/2g'</code>

<code>abABABABABABAB</code>

<code>[root@zxq ~]</code><code># echo ababababababab | sed 's/ab/AB/3g'</code>

<code>ababABABABABAB</code>

<code>[root@zxq ~]</code><code># echo ababababababab | sed 's/ab/AB/4g'</code>

<code>abababABABABAB</code>

<code>[root@zxq ~]</code><code># echo ababababababab | sed 's/ab/AB/5g'</code>

<code>ababababABABAB</code>

以上指令中/在sed中作為定界符使用,也可以使用任意的定界符,例如使用#号将輸出内容轉換成大寫,其中的U在元字元裡是大寫大意思,&amp;代表已比對的字元。

<code>[root@zxq ~]</code><code># echo abcd |sed 's#[a-z]#\U&amp;#g'</code>

<code>ABCD</code>

删除操作:d指令 

<code>删除空白行</code>

<code>sed</code> <code>'/^$/d'</code> <code>file</code>

<code>删除檔案的第2行</code>

<code>sed</code> <code>'2d'</code> <code>file</code>

<code>删除檔案的第2行到末尾所有行</code>

<code>sed</code> <code>'2,$d'</code> <code>file</code>

<code>删除檔案最後一行</code>

<code>sed</code> <code>'$d'</code> <code>file11</code>

<code>删除檔案中所有開頭的</code><code>test</code><code>的行</code>

<code>sed</code> <code>'/^test/d'</code> <code>file</code>

已比對字元串标記&amp; 

正規表達式\w+比對每一個單詞,使用[&amp;]替換它,&amp;對于之前所比對到的單詞

<code>[root@zxq ~]</code><code># echo a b c d |sed 's/\w\+/[&amp;]/g'</code>

<code>[a] [b] [c] [d]</code>

&amp;代表前面比對的内容然後加上後面需要替換的内容:

<code>[root@zxq ~]</code><code># echo "202.106.0.20"|sed 's/202.106.0.20/&amp;DNS/g'</code>

<code>202.106.0.20DNS</code>

子串比對标記 \1 

比對給定樣式的其中一部分,第一個使用\1第二個使用\2,下面是截取IP和mac位址

<code>[root@zxq ~]</code><code># ifconfig eth0|sed -n 's/^.*addr:\(.*\)  .*  Mask:\(.*\)$/ip:\1 mac:\2/gp'</code>

<code>ip:10.0.0.4 mac:255.255.255.0</code>

指令中第一個()内的内容比對\1,第二個()内大内容比對\2,依此類推 

例如:[a-z]+代表任意字元後面的+是多個的意思,此處使用-r選項使用延伸的正規表達式,就不需要對特殊字元轉義了。

<code>[root@zxq ~]</code><code># echo "aaa BBB"|sed -r 's/([a-z]+) ([A-Z]+)/\2 \1/'</code>

<code>BBB aaa</code>

引用 

sed表達式可以使用單引号來引用,但是如果表達式内部包含變量字元串,就需要使用雙引号

<code>[root@zxq ~]</code><code># aa=mysql;echo "this is sqlserver"|sed 's/sqlserver/$aa/'</code>

<code>this is $aa</code>

<code>[root@zxq ~]</code><code># aa=mysql;echo "this is sqlserver"|sed "s/sqlserver/$aa/"</code>

<code>this is mysql</code>

標明行的範圍: ,逗号 

所有在模闆bbb和ddd所确定的範圍内的行都被列印

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\nccc\nddd"|sed -n '/bbb/,/ddd/p'</code>

<code>bbb</code>

<code>ccc</code>

<code>ddd</code>

列印從第2行開始到第一個包含以ccc開始的行之間的所有行包括ccc:

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\nccc\nddd"|sed -n '2,/^ccc/p'</code>

對于aaa和ccc之間的行,每行的末尾追加www.com

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\nccc\nddd"|sed '/aaa/,/ccc/s/$/www.com/'</code>

<code>aaawww.com</code>

<code>bbbwww.com</code>

<code>cccwww.com</code>

多點編輯:e 指令

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\nccc\nddd\neee"|sed -e '1,3d' -e 's/eee/www/'</code>

<code>www</code>

上面sed表達式的第一條指令删除1至3行,第二條指令用eee替換www,指令的執行順序對結果有影響,如果兩個 指令都是替換指令,那麼第一個指令将 影響第二個替換指令的結果

和-e等價的指令是–expression

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\nccc\nddd\neee"|sed --expression 's/aaa/MMM/' --expression 's/eee/www/'</code>

<code>MMM</code>

從檔案讀入: r指令 

file裡面的内容被讀進來,顯示在與aaa比對的行後面,如果比對多行,則file的内容将顯示在所有比對行的後面sed '/aaa/r filename

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed '/aaa/r aa.txt'</code>

<code>aaa</code>

<code>www.org</code>

<code>blog.com</code>

<code>eee</code>

從檔案寫入:w指令

将比對的行寫入到檔案内,注意會覆寫原檔案内容

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed -n '/aaa/w aa.txt'</code>

追加: a\ 指令 

将www.gun.org追加到以aaa開頭的行後面 

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed '/^aaa/a\www.gun.org'</code>

<code>www.gun.org</code>

在檔案第2行之後追加www,centos.org 

<code>[root@zxq ~]</code><code># sed -i '2a\www.centos.org' aa.txt </code>

<code>www.centos.org</code>

插入: i\ 指令

在比對的行前面插入内容

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed '/^aaa/i\www.gun.org'</code>

下一個 n/N 指令 

:label将存儲一個标簽位置,使用N追加下一行文本到此空間,此處就有了兩行文本(aa$bb),然後使用s/\n//p替換功能替換換行符(\n),輸出aabb,b将跳轉标簽位為bb後,指派給label。然後逐行執行語句到行尾。

<code>[root@pjy ~]</code><code># cat a.txt </code>

<code>aa</code>

<code>bb</code>

<code>cc</code>

<code>[root@pjy ~]</code><code># sed ':label;N;s/\n//p;b label' a.txt </code>

<code>aabb</code>

<code>aabbcc</code>

變形: y指令 

把1~10行内所有abcde轉變為大寫,注意,正規表達式元字元不能使用這個指令 

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed '1,4y/abcde/ABCDE/'</code>

<code>AAA</code>

<code>BBB</code>

<code>DDD</code>

退出 q指令 

列印完第10行後,退出sed

sed '10q' file

列印奇數行或偶數行

方法1,使用n指令下一行列印

<code>列印奇數行:</code>

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed -n 'p;n'</code>

<code>列印偶數行:</code>

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed -n 'n;p'</code>

方法2,指定從第幾行開始列印,後面數字指定間隔幾行列印

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed -n '1~2p'</code>

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed -n '2~2p'</code>

列印比對字元串的下一行

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed -n '/ddd/{n;p}'</code>

使用b做跳轉,當判斷字元為aaa時b就跳轉到x,此處的:x為定義的标簽,标簽後為執行的動作。比對字元aa就跳轉到x執行動作,在aa後面添加制表符和YES,如果不為aa就不跳轉直接執行後面的s/$/\tYES/,在後面添加制表符和YES。

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed '/^aaa/bx;s/$/\tNO/;b;:x;s/$/\tYES/'</code>

<code>aaaYES</code>

<code>bbbNO</code>

<code>dddNO</code>

<code>eeeNO</code>

<code>使用t做跳轉時,如果有一次成功的替換則讀入最後一個T或t指令,此處還是不太明白,有懂的大神希望留言告知。</code>

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed '/^aaa/tx;s/$/\tNO/;t;:x;s/$/\tYES/'</code>

<code>aaaNO</code>

<code>使用T做跳轉時,如果有一次成功的替換則讀入最後一個T或t指令,使用取反跳轉,此處還是不太明白,有懂的大神希望留言告知。</code>

<code>[root@zxq ~]</code><code># echo -e "aaa\nbbb\naaa\nddd\neee"|sed '/^aaa/Tx;s/$/\tNO/;T;:x;s/$/\tYES/'</code>

<code>bbbNOYES</code>

<code>dddNOYES</code>

<code>eeeNOYES</code>

分析多行日志取IP和mac位址并做統計執行個體:

<code>grep</code> <code>-wE </code><code>'^lease|hardware'</code> <code>$patha</code><code>/dhcpd</code><code>.leases|</code><code>sed</code> <code>':x;N;s/{\n//;b x'</code><code>|</code><code>sed</code> <code>-n </code><code>"s/;$//gp"</code><code>|</code><code>awk</code> <code>'BEGIN{print "IP""\t\t""MAC"} {print $2"\t"$5}'</code> <code>&gt;$patha</code><code>/ip_table</code><code>.txt</code>

<code>cat</code> <code>$patha</code><code>/ip_table</code><code>.txt | </code><code>wc</code> <code>-l &gt; $patha</code><code>/aa</code><code>.txt</code>

後期補充。。。。

本文轉自 80後小菜鳥 51CTO部落格,原文連結:http://blog.51cto.com/zhangxinqi/1921804

繼續閱讀