1. 程式人生 > 實用技巧 >shell 指令碼-sed工具

shell 指令碼-sed工具

sed 是一種線上編輯器,它一次處理一行內容。處理時,把當前處理的行儲存在臨時緩衝

區中,稱為 模式空間 pattern space),接著用 sed命令處理緩衝區中的內容,處理完成後,

把緩衝區的內容送往螢幕。接著處理下一行,這樣不斷重複,直到檔案末尾。檔案內容並

沒有 改變,除非你使用重定向儲存輸出。 Sed主要用來自動編輯一個或多個檔案;簡化對文

件的反覆操作;

基本使用:

1. /pattern/p :列印匹配pattern的行

使用 p命令需要注意 ,sed 是把待處理檔案的內容連同處理結果一起輸出到標準輸出的 ,因此

p命令 表示除了把檔案內容打印出來之外還額外列印一遍匹配 pattern的行。比如一個文

log的內 容是

要想只輸出處理結果 ,應加上 -n選項 ,這種用法相當於 grep命令

[[email protected]sed]$sed'//p'file
11111111111111111111
2222222222222222222
3333333333333333333
44444444444444444
5555555555555555555
[[email protected]sed]$sed'/*/p'file
11111111111111111111
2222222222222222222
3333333333333333333
44444444444444444
5555555555555555555
[
[email protected]
sed]$sed'/1/p'file 11111111111111111111 11111111111111111111 2222222222222222222 3333333333333333333 44444444444444444 5555555555555555555 [[email protected]sed]$sed'/.*/p'file 11111111111111111111 11111111111111111111 2222222222222222222 2222222222222222222 3333333333333333333 3333333333333333333 44444444444444444 44444444444444444 5555555555555555555 5555555555555555555 [
[email protected]
sed]$sed-n'/.*/p'file 11111111111111111111 2222222222222222222 3333333333333333333 44444444444444444 5555555555555555555

2. /pattern/d :刪除匹配pattern的行

注意,sed命令不會修改原檔案,刪除命令只表示某些行不列印輸出 ,而不是從原檔案中刪去。

[[email protected]sed]$sed'/11*/d'file
2222222222222222222
3333333333333333333
44444444444444444
5555555555555555555

3. /pattern/s/pattern1/pattern2/ :查詢符合pattern的行 ,將該行第一個匹配

pattern1的字串替換為pattern2

4. /pattern/s/pattern1/pattern2/g :查詢符合pattern的行 ,將該行所有匹配

pattern1的字串替換為pattern2

[[email protected]sed]$catfile
aabbccdd
aabbaabb
aabbaabb
[[email protected]sed]$sed'/aa*/s/aa/ff/'file
ffbbccdd
ffbbaabb
ffbbaabb
[[email protected]sed]$sed'/aa*/s/aa/ff/g'file
ffbbccdd
ffbbffbb
ffbbffbb
[[email protected]sed]$sed'/a/s/a/-f-/g'file
-f--f-bbccdd
-f--f-bb-f--f-bb
-f--f-bb-f--f-bb


[[email protected]sed]$sed'/^[a-z]\+/s/\([a-c]\+\)/\1--/'file
aabbcc--dd
aabbaabb--
aabbaabb--

pattern2中的& 表示原檔案的當前行中與pattern1匹配的字串

[[email protected]sed]$sed'/^[a-z]\+/s/\([a-c]\+\)/\-&-/'file
-aabbcc-dd
-aabbaabb-
-aabbaabb-

pattern2中的\1 表示與pattern1的第一個 ()括號相匹配的內容 ,\2表示與 pattern1

第二個()括號 相匹配的內容。


sed預設使用Basic正則表示式規範,如果指定了-r選項則使Extended規範 ,那 麼 ()括號就不必轉義了

[[email protected]sed]$catf1
<html><head><title>HelloWorld</title>
<body>Welcometotheworldofregexp!</body></html>


sed/grep 匹配 是貪心的 總是匹配最長的 所以下面方法是錯誤的

wKiom1e6_bCSmtZcAABI9bthQTo872.png

下面才是去除<。。。>的正確方法 用[]做限定 防止<>中間再有< 或> 把整句都匹配了wKiom1e6_dXTdnOjAAAnqdutoy8629.png

5. sed -i : 做的操作會修改原檔案

[[email protected]sed]$catf2
11111111111
22222222222
33333333333
[[email protected]sed]$sed'$d'f2
11111111111
22222222222
[[email protected]sed]$catf2
11111111111
22222222222
33333333333
[[email protected]sed]$sed-i'$d'f2
[[email protected]sed]$catf2
11111111111
22222222222


6. 定址

定址用於決定對哪些行進行編輯。地址的形式可以是數字、正則表示式、或二者的結合。

如果沒有指定地址, sed將處理輸入檔案的所有行。

sed -n ‘3p’ file #列印第三行

sed -n ‘100,300p’ file # 列印100 300行的資訊(包括 100 300

地址是逗號分隔的,那麼需要處理的地址是這兩行之間的範圍(包括這兩行在內)。

圍可以用數字、正則表示式、或二者的組合表示。

sed ‘25d’ file #刪除第二行到第五行

sed ‘/start/ ,/end/d’ file # 刪除包含’start’行和 ’end’行之間的行

sed ‘/start/, 10d’ file # 刪除包含’start’ 的行到第十行的內容

等等,例子如下:

[[email protected]sed]$catf2
11111111111
start
22222222222
33333333333
44444444444444
555555555
end
66666666
7777777

[[email protected]sed]$sed-n'/start/,8p'f2
start
22222222222
33333333333
44444444444444
555555555
end
66666666
[[email protected]sed]$sed-n'/start/,/end/p'f2
start
22222222222
33333333333
44444444444444
555555555
end
[[email protected]sed]$sed-n'4p'f2
33333333333
[[email protected]sed]$sed-n'2,4p'f2
start
22222222222
33333333333


[[email protected]sed]$seq6|sed-n'2,4p'
2
3
4



’0~3p‘表示 從0開始 每次行號加3的行 ~表示每次行號加幾

[[email protected]sed]$seq6|sed-n'0~3p'
3
6
[[email protected]sed]$seq6|sed-n'0~2p'
2
4
6
[[email protected]sed]$seq6|sed-n'0~1p'
1
2
3
4
5
6

7. 命令和選項

sed命令告訴sed 如何處理由地址指定的各輸入行,如果沒有指定地址則處理所有的輸入

行。

命令

a\ :在當前行後新增一行或多行。多行時除最後一行外,每行末尾需用 “\”續行

[[email protected]sed]$sed'2anihao\hello'f3
11111111111
22222222222
nihaohello
33333333333
44444444444



c\ :用此符號後的新文字替換當前行中的文字。多行時除最後一行外,每行末尾需用 ”\"

續行

i\ :在當前行之前插入文字。多行時除最後一行外,每行末尾需用 ”\"續行 d刪除行

[[email protected]sed]$sed'2inihao\hello'f3
11111111111
nihaohello
22222222222
33333333333
44444444444


h : 把模式空間裡的內容複製到暫存緩衝區

H :把模式空間裡的內容追加到暫存緩衝區

g :把暫存緩衝區裡的內容複製到模式空間,覆蓋原有的內容

G:把暫存緩衝區的內容追加到模式空間裡,追加在原有內容的後面

l :列出非列印字元

p :列印行

n :讀入下一輸入行,並從下一條命令而不是第一條命令開始對其的處理

q :結束或退出sed

r :從檔案中讀取輸入行

! : 對所選行以外的所有行應用命令

s :用一個字串替換另一個

g :在行內進行全域性替換

w :將所選的行寫入檔案

x :交換暫存緩衝區與模式空間的內容

y :將字元替換為另一字元(不能對正則表示式使用 y命令)



選項

-e :進行多項編輯,即對輸入行應用多條 sed命令時使用

[[email protected]sed]$seq6|sed-e'1d'-e'5d'
2
3
4
6

-n :取消預設的輸出

-f :指定sed 指令碼的檔名

8. 退出狀態

sed不向grep 一樣,不管是否找到指定的模式,它的退出狀態都是 0。只有當命令存在語法

錯誤時, sed的退出狀態才不是 0


正則表示式 練習

sed使用的正則表示式是括在斜槓線 "/"之間的模式。如果要把正則表示式分隔符 "/"改為另一個字元,比如 o,只要在這個字元前加一個反斜線,

在字元後跟上正則表示式,再跟上這個字元即可。例如: sed -n '\o^Myop' datafile

[[email protected]sed]$sed-n'\u^myup'log
my1111111


^:行首定位符:/^my/ 匹配所有以 my開頭的行

[[email protected]sed]$catlog
111111111
my1111111
11my
111111111my
3333333333
[[email protected]sed]$sed-n'/^my/p'log
my1111111

$:行尾定位符:/my$/ 匹配所有以 my結尾的行

[[email protected]sed]$sed-n'/my$/p'log
11my
111111111my


.:匹配除換行符以外的單個字元: /m..y/ 匹配包含字母 m,後跟兩個任意字元,再跟字y的行

[[email protected]sed]$sed-n'/1..y/p'log
11my
111111111my

*:匹配零個或多個前導字元: /test*/ 匹配包含 string tes,後跟零個或多個 t字母的行

[[email protected]sed]$sed-n'/test*/p'f4
test
testy
tesa
tests
testttt
[[email protected]sed]$catf4
test
testy
tesa
tests
testttt
tea
tebs

[]:匹配指定字元組內的任一字元 : /t[eE]st/ 匹配包含 test tEst的行

[[email protected]sed]$catf4
test
tebs
tEsta
tEstsad
tast
tfst
[[email protected]sed]$sed-n'/t[eE]st/p'f4
test
tEsta
tEstsad

[^]:匹配不在指定字元組內的任一字元: /t[^eE]st/ 匹配 string t開頭,但 st之前的

那個字元不是 e E的行

[[email protected]sed]$catf4
test
tebs
tEsta
tEstsad
tast
tfst
[[email protected]sed]$sed-n'/t[^eE]st/p'f4
tast
tfst

\(..\):儲存已匹配的字元: 標記元字元之間的模式,並將其儲存為標籤 1,之後可以使用

\1來引用它。最多可以定義 9個標籤,從左邊開始編號,最左邊的是第一個。此例中,對第

1到第3 行進行處理, tes被儲存為標籤 1,如果發現 tes或tEs,則替換為 tes-或tEs

[[email protected]sed]$catf4
test
tebs
tEsta
tEstsad
tast
tfst
[[email protected]sed]$sed'1,3s/\(t[Ee]s\)/\1-/g'f4
tes-t
tebs
tEs-ta
tEstsad
tast
tfst


&:儲存查詢串以便在替換串中引用: s/test/*&*/g 符號& 代表查詢串。test將被替換為

*test*

[[email protected]sed]$catf4
test
tebs
tEsta
tEstsad
tast
tfst
[[email protected]sed]$sed's/t[eE]st/*&*/g'f4
*test*
tebs
*tEst*a
*tEst*sad
tast
tfst


\<:詞首定位符:/\<my/ 匹配包含以 my開頭的單詞的行

[[email protected]sed]$catf4
test
tebs
tEsta
tEstsad
tast
tfst
[[email protected]sed]$sed-n'/\<te/p'f4
test
tebs


\>:詞尾定位符:/my\>/ 匹配包含以 my結尾的單詞的行

[[email protected]sed]$catf4
test
tebs
tEsta
tEstsad
tast
tfst
[[email protected]sed]$sed-n'/st\>/p'f4
test
tast
tfst


x\{m\}:連續m x /m\{5\}/ 匹配包含連續5m的行

[[email protected]sed]$catf4
test
tebs
tEsta
tEstsad
tast
tfst
OOOOmmmmmmmmmUUUU
[[email protected]sed]$sed-n'/\m\{5\}/p'f4
OOOOmmmmmmmmmUUUU

x\{m,\}:至少m x /m\{5,\}/ 匹配包含至少連續 5m的行

[[email protected]sed]$catf4
test
tebs
tEsta
tEstsad
tast
mmmmm
mmmmmm
OOOOmmmmmmmmmUUUU
mmmm
[[email protected]sed]$sed-n'/m\{5,\}/p'f4
mmmmm
mmmmmm
OOOOmmmmmmmmmUUUU


x\{m,n\}:至少m 個,但不超過n x /m\{5,7\}/ 匹配包含連續 5 7m的行

[[email protected]sed]$catf4
test
tebs
tEsta
tEstsad
tast
mmmmm
mmmmmm
OOOOmmmmmmmmmUUUU
mmmm
[[email protected]sed]$sed-n'/m\{5,7\}/p'f4
mmmmm
mmmmmm
OOOOmmmmmmmmmUUUU【注意這個還是會匹配到的】


模式空間保持空間(高階用法,難度較高)

sed在正常情況下,將處理的行讀入模式空間 pattern space),指令碼中的“sedcommand sed命令) 就一條接著一條進行處理,直到指令碼執行完畢。然後該行唄輸出,模式( pattern space)被清空;接著,在重複執行剛才的動作,檔案中的

新的一行被讀入,直到檔案處理完畢。

wKioL1e6_h7wHozqAADI84nu47E167.png

一般情況下,資料的處理只使用模式空間 pattern space),按照如上的邏輯即可

完成主要任務。但是某些時候,使用通過使用保持空間( hold space),還可以帶

來意想不到的效果。

模式空間:可以想成工程裡面的流水線,資料之間在它上面進行處理。

保持空間:可以想象成倉庫,我們在進行資料處理的時候,作為資料的暫存區域。

正常情況下,如果不顯示使用某些高階命令,保持空間不會使用到!


小寫命令 表示 清除

大寫的命令 表示 追加

+ g [address[,address]]g hold space 中的內容拷貝到 pattern space中,

原來pattern space裡的內容清除

+ G [address[,address]]G hold space 中的內容append pattern

space\n

+ h [address[,address]]h pattern space 中的內容拷貝到 hold space中,

原來的hold space裡的內容被清除

+ H [address[,address]]H pattern space 中的內容append hold

space\n

+ d [address[,address]]d 刪除pattern中的所有行,並讀入下一新行到

pattern

+ D [address[,address]]D 刪除multiline pattern 中的第一行,不讀入下一行

+ x:交換保持空間和模式空間的內容


例子:

1. 給每行結尾新增一行空行

[[email protected]sed]$catf5
0hello
1hello
2hello
3hello
4hello
5hello
6hello
7hello
[[email protected]sed]$sed'G'f5【模式空間為空按行處理追加到模式空間就相當於追加空行】
0hello

1hello

2hello

3hello

4hello

5hello

6hello

7hello

[[email protected]sed]$


2. sed 模擬出tac的功能(倒序輸出)

[[email protected]sed]$seq10>f6
[[email protected]sed]$catf6
1
2
3
4
5
6
7
8
9
10

先理解這個

[[email protected] sed]$ sed 'G;h;' f6 【先將保持空間的 追加到模式空間 (第一次是空 所以1後面是空 ) 然後是將模式空間的(1 空 )拷貝到保持空間 輸出 下一次從保持空間 到 模式空間追加的就是 (1 空 ) 所以第二次為 2 1 空 以此類推】

1

2
1

3
2
1

4
3
2
1

5
4
3
2
1

6
5
4
3
2
1

7
6
5
4
3
2
1

8
7
6
5
4
3
2
1

9
8
7
6
5
4
3
2
1

10
9
8
7
6
5
4
3
2
1

再理解這個

[[email protected]sed]$sed'G;h;2,3!d'f6【2,3!d】表示按行刪除時第二次和第三次處理時候不刪除模式空間的所有行
2
1

3
2
1

最後理解這個

1!G1 行不執行“G”命令,從第 2行開始執行。 $!d,最後一行不刪除(保留最後 1行)

[[email protected]sed]$sed'1!G;h;$!d'f6【1!G】表示再追加的時候第一次按行處理是不追加保持空間的空行到模式空間
10
9
8
7
6
5
4
3
2
1

wKiom1e6_k7gLLGlAAFdCYRvzpI267.png

3.追加匹配行到檔案結尾

[[email protected]sed]$catf5
0hello
1hello
2hello
3hello
4hello
5hello
6hello
7hello
[[email protected]sed]$sed-e'/[234].*/H'-e'$G'f5
0hello
1hello
2hello
3hello
4hello
5hello
6hello
7hello

2hello
3hello
4hello

4.行列轉化

[[email protected]sed]$catf6
1
2
3
4
5
6
7
8
9
10
[[email protected]sed]$sed-n'H;${x;s/\n/-/g;p}'f6
-1-2-3-4-5-6-7-8-9-10【說明每行顯示是最前面有一個\n被替換】
[[email protected]sed]$sed-n'H;${x;s/\n//g;p}'f6
12345678910
[[email protected]sed]$sed-n'H;${x;s/\n//g;p}'f6
12345678910

H表示把pattern space的內容追加到hold space中去,H可以帶一個地址,這裡

用的是$,表示到檔案的末尾,然後用x將之取到pattern space中,把\n替換成空格再列印即可。


5.同上,求1100的求和

[[email protected]sed]$seq100|sed-n'H;${x;s/\n/+/g;s/^+//;p}'
1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100
[[email protected]sed]$seq100|sed-n'H;${x;s/\n/+/g;s/^+//;p}'|bc
5050


6.列印奇偶數行

[[email protected]sed]$catf6
1
2
3
4
5
6
[[email protected]sed]$sed-n'n;p'f6【'n;p'n是清除當前行讀取下一行】
2
4
6
[[email protected]sed]$sed-n'p;n'f6
1
3
5
[[email protected]sed]$sed-n'n;n;p'f6
3
6

7.1100求和

先看這個

[[email protected]sed]$seq10|sed':a;N;s/\n/+/;'【N表示多讀取一行】
1+2
3+4
5+6
7+8
9+10

再看這個

[[email protected]sed]$seq10|sed':a;N;s/\n/+/;ba'
1+2+3+4+5+6+7+8+9+10
[[email protected]sed]$seq10|sed':c;N;s/\n/+/;bc'
1+2+3+4+5+6+7+8+9+10
[[email protected]sed]$seq100|sed':c;N;s/\n/+/;bc'|bc
5050
[[email protected]sed]$seq100|sed':f;N;s/\n/+/;bf'|bc
5050

:a表示標籤aba表示跳轉到a標籤,$表示最後一行,!表示不做後續操作,所

以,$!ba表示最後一行不用跳轉到a標籤,結束此次操作。

相關部落格:

討論:互換模式空間和保持空間的內容

http://blog.chinaunix.net/uid-10540984-id-316081.html

http://oldboy.blog.51cto.com/2561410/767862/

http://blog.chinaunix.net/uid-9950859-id-98222.html

http://czmmiao.iteye.com/blog/1899880

http://blog.sina.com.cn/s/blog_46ecf5890100jtip.htmlvised結合)


轉載於:https://blog.51cto.com/alick/1841255