流編輯器sed使用總結及利用sed從文本中提取字串的方法,編輯器sed
sed 是一個編輯器,但它與其它大多數編輯器不同。除了不面向螢幕之外,它還是非互動,我們常用的vim編輯器則是互動。
這意味著必須將要對資料執行的命令插入到命令列或要處 理的指令碼中。sed 在一個檔案(或檔案集)中非互動式、並且不加詢問地接收一系列的命令並執行它們。因而,它流經文本就如同水流經溪流一樣,因而 sed 恰當地代表了流編輯器,可以對檔案或者檔案集批量的進行刪除 替換 插入 追加等操作。
流編輯器非常適合於執行重複的編輯,這種重複編輯如果由人工完成將花費大量的時間。
其參數可能和一次性使用一個簡單的操作所需的參數一樣有限, 或者和一個具有成千上萬行要進行編輯修改的指令檔一樣複雜。
這正是我們常用的互動式編輯器VIM的缺點所在啊,所以2者結合,非常實用!
sed 是 Linux 和 UNIX 工具箱中最有用的工具之一,且使用的參數非常少。
sed每次從輸入(該輸入可以是管道或者檔案)中讀取一行,用提供的編輯命令匹配資料、按命令中指定的方式修改流中的資料,然後產生的資料輸出到STDOUT。在流編輯器將所有命令與一行資料進行匹配後,它會讀取下一行資料並重複這個過程。在流編輯器處理完流中的所有資料行後,它就會停止。
sed命令列格式為:
sed [-nefri] ‘command’ 輸入文本
常用選項:
-n∶使用安靜(silent)模式。sed預設的處理結果是輸出到STDOUT。但如果加上 -n 參數後,則只有經過sed 特殊處理的那一行(或者動作)才會被列出來。
-e∶直接在指令列模式上進行 sed 的動作編輯(可以同時執行多條操作命令);
-f∶直接將 sed 的動作寫在一個檔案內, -f filename 則可以執行 filename 內的sed 動作;
-r∶sed 的動作命令是擴充型Regex。(預設是基礎Regex)
-i∶直接修改讀取的檔案內容,而不是由STDOUT輸出。
常用命令:
a ∶新增, a 的後面可以接字串,而這些字串會在新的一行出現(目前的下一行)
c ∶取代, c 的後面可以接字串,這些字串可以取代 n1,n2 之間的行!
d ∶刪除,刪除行;
i ∶插入, i 的後面可以接字串,而這些字串會在新的一行出現(目前的上一行);
p ∶列印,亦即將某個選擇的資料印出。可用於尋找功能,sed -n ‘/尋找字串/p’可實現對字串的尋找,類似於grep。通常 p 會與參數 sed -n 一起運作
s ∶取代,直接進行取代的工作,通常這個 s 的動作可以搭配Regex
下面來詳細說一下sed的使用方法
1)在命令列定義編輯命令
$ echo "This is a test" | sed 's/test/big test/'
This is a big test
$ cat data1
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$ sed 's/dog/cat/' data1
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
2)在命令列使用多個編輯器命令(要使用-e選項)
$ sed -e 's/brown/green/; s/dog/cat/' data1
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
3)從檔案中讀取編輯器命令(使用-f選項)
$ cat script1.sed
s/brown/green/
s/fox/elephant/
s/dog/cat/
$ sed -f script1.sed data1
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
4)替換標記
關於substitute命令如何替換字串中匹配的模式需要注意一點,就是在預設情況下它只替換每行中出現的第一處。要讓替換命令對一行中不同地方出現的文本都起作用,必須使用替換標記(substitution flag)
s/pattern/repacement/flags
1> 數字,表明新文本將替換第幾處模式比對的地方;
2> g,表明新文本將會替換所有已有文本出現的地方;
3> p,表明原來行的內容要列印出來;
4> w file,將替換原來行的結果寫到檔案中。
$ echo "This is a test" | sed -n 's/test/big test/p'
This is a big test
注意:-n選項將禁止sed編輯器輸出,但p替換標記會輸出修改過的行,將二者配合全盤則會只輸出被substitute命令修改過的行。
5)替換字元
$ sed 's/\bin\/bash/\/bin\/csh/' /etc/passwd
sed編輯器可以用驚嘆號用作分隔字元,使得路徑名更容易被讀取和理解
$ sed 's!/bin/bash!/bin/cash!' /etc/passwd
6)使用地址
預設情況下,在sed編輯器中使用的命令會作用於文本資料的所有行。如果只想作用於特定的某行或某些行,你必須用行定址(line addressing)。
在sed編輯器中有兩種形式的行定址:
1》行的數字範圍;
2》用文字模式來過濾出某行。
兩種形式都使用相同的格式來指定地址:
[address]command
也可以為特定的地址將多個命令放在一起:
address{
command1
command2
command3
}
1> 數字方式的行定址
$ sed '2s/dog/cat/' data1
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$ sed '2,3s/dog/cat/' data1
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
$ sed '2,$s/dog/cat/' data1
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
2> 使用文字模式過濾器
格式如下:
/pattern/command
$ echo "This is a test" | sed '/test/s/test/TEST/'
This is a TEST
3> 組合命令
如果需要在單行上執行多條命令,可以用花括弧將多條命令組合在一起。
$ sed '2{
> s/fox/elelhant/
> s/dog/cat/
> }' data1
The quick brown fox jumps over the lazy dog.
The quick brown elelhant jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
7)刪除行
$ cat data2
line1
line2
line3
line4
$ sed '3d' data2
line1
line2
line4
你可以刪除用兩個文字模式來刪除某個範圍內的行,但這麼做時要小心。你指定的第一個模式會“開啟”行刪除功能,第二個模式會“關閉”行刪除功能。sed編輯器會刪除兩個指定行之間的所有行(包括指定的行)
$ sed '/1/,/3/d' data2
line4
如果“開啟”了刪除功能,而沒有“關閉”,則會刪除之後所有的資料。
$ sed '/1/,/5/d' data2
8)插入和附加文本
1》插入(insert)命令i會在指定行前增加一個新行;
2》追加(append)命令a會在指定行後增加一個新行。
不能在單個命令列上使用這兩條命令。你必須指定是要將行插入還是附加到另一行。格式如下:
sed '[address]command\
new line'
new line中文本將會出現在sed編輯器輸出中你指定的位置。記住,當使用插入命令時,文本會出現在資料流文本的前面,而當使用附加命令時,文本會出現在資料流文本的後面:
$ echo "Test line 2" | sed 'i\Test line 1'
Test line 1
Test line 2
$ echo "Test line 2" | sed 'a\Test line 1'
Test line 2
Test line 1
9)修改行
修改(change)命令允許修改資料流中整行文本的內容。它跟插入和附加命令的工作機制一樣,你必須在sed命令中單獨指定新行。
$ sed '3c\This is a changed line' ./data2
line1
line2
This is a changed line
line4
也可以在修改命令中使用地址區間,但結果可能不是你想要的(因為它是包括區間所在的行):
$ sed '2,3c\This is a changed line' ./data2
line1
This is a changed line
line4
10)轉換命令
轉換(transform, y)命令是唯一可以處理單個字元的sed編輯命令。轉換命令格式如下:
[address]y/inchars/outchars/
轉換命令會進行inchars和outchars值一對一映射。
$ sed 'y/1234/6789/' data2
line6
line7
line8
line9
轉換命令是全域的,也就是說,它會自動替換文本行中找到的指定字元的所有執行個體,
$ echo "this 1 is a test of 1 try." | sed 'y/123/456/'
this 4 is a test of 4 try.
11)回顧列印
這裡有3條也能用來列印資料流中的資訊的命令:
1> 小寫p命令用來列印文本行;
2> 等號(=)命令用來列印等號;
3> 小寫l命令用來列出行。
$ echo "This is a test" | sed 'p'
This is a test
This is a test
$ sed '=' data1
1
The quick brown fox jumps over the lazy dog.
2
The quick brown fox jumps over the lazy dog.
3
The quick brown fox jumps over the lazy dog.
4
The quick brown fox jumps over the lazy dog.
上面介紹了sed的一些基礎使用方法,下面就我實際遇到的一個問題來實戰一下!
現在需要在kernel啟動後解析kernel的commandline,來擷取需要設定的ip netmask等網路參數。
首先查看/proc/cmdline,如下:
console=ttyS0,115200 rdinit=/sbin/init ipaddr=10.0.14.143 netmask=255.255.255.252 gw=10.0.12.1
當然可以寫個程式,進行字串分析,這是最保守的方法,也是最笨的方法。。。需要自己去寫字串分析。
還是要用最簡單的方法來解決問題才好。
在指令碼中用sed實現如下:
#!/bin/baship=`sed -n 's/ /\n/gp' /proc/cmdline | sed -n '/ipaddr/p' | sed -n 's/ipaddr=//gp'`netmask=`sed -n 's/ /\n/gp' /proc/cmdline | sed -n '/netmask/p' | sed -n 's/netmask=//gp'`gw=`sed -n 's/ /\n/gp' /proc/cmdline | sed -n '/gw/p' | sed -n 's/gw=//gp'`if [ "$ip" != "" -a "$netmask" != "" ]; then ifconfig eth0 $ip netmask $netmaskfiif [ "$gw" != "" ]; then route add default gw $gw fi
這個指令碼就可以實現ipaddr netmask gw字串的提取,以及使用。
新手用shell時 , 用sed從文本中取出了字串(全是數字), 我想把它賦值到一個變數n上,
n=`sed **** | awk '{printf "%d",$0}'`----sed就是你的事情了。。。
linux 下用shell sed替換文本中的字串
sed 'N;s/Hour\n/Hour/' tt.txt