天天看點

linux下sed的使用(下)

linux下sed的使用(下)

本篇主要講解:

---sed的導入和導出

sed資料的導入和導出(是一種非互動式的導入和導出,可用在腳本中)

r      導入 (把其他檔案的内容放到目前檔案裡)

w     導出   (檔案另存為)

Sed導入格式

sed     -i ‘定址符r      檔案A’  檔案B

把檔案A的資料導入到 檔案B裡

導入的時候是逐行導入的,B檔案必須事先存在,且最少有一行,一行都沒有的情況下是導入不了的

–預設會逐行導入

–使用定址符限制輸入資料的位置

–定址符可以使用行号、正規表達式表示

Sed導出格式

sed     -i ‘定址符w    檔案A’  檔案B

把檔案B的資料導出到 檔案A裡(另存為)

–覆寫導出

–檔案A不用事先建立

–若檔案A事先存在 會覆寫其内的資料

一、

1.sed導入導出的基本用法

1)r 讀入其他檔案内容。

以前面的rclocal.txt檔案為例,确認檔案内容:

<code>[root@svr5 ~]</code><code># cat rclocal.txt</code>

<code>1 </code><code>#!/bin/sh</code>

<code>2 </code><code>#</code>

<code>3 </code><code># This script will be executed *after* all the other init scripts.</code>

<code>.4 </code><code># You can put your own initialization stuff in here if you don't</code>

<code>5 </code><code># want to do the full Sys V style init stuff.</code>

<code>6</code>

<code>7 </code><code>touch</code> <code>/var/lock/subsys/local</code>

讀入/etc/sysconfig/network檔案的全部内容,插入到rclocal.txt檔案的第5行之後(注意:需加-i才真的儲存,否則隻輸出結果):

<code>[root@svr5 ~]</code><code># sed '5r /etc/sysconfig/network' rclocal.txt</code>

<code>4 </code><code># You can put your own initialization stuff in here if you don't</code>

<code>NETWORKING=</code><code>yes</code>

<code>NETWORKING_IPV6=no</code>

<code>HOSTNAME=svr5.tarena.com</code>

在rclocal.txt檔案的每一行下方都插入/etc/sysconfig/network檔案的内容:

<code>[root@svr5 ~]</code><code># sed 'r /etc/sysconfig/network' rclocal.txt</code>

<code>.. ..</code>

2)w 将過濾結果儲存到指定的檔案。

将rclocal.txt檔案的第2-5行儲存為/tmp/out.txt檔案:

<code>[root@svr5 ~]</code><code># sed -n '2,5w /tmp/out.txt' rclocal.txt</code>

<code>[root@svr5 ~]</code><code># cat /tmp/out.txt</code>

上述操作與改用p重定向的效果相同:

<code>[root@svr5 ~]</code><code># sed -n '2,5p' rclocal.txt &gt; /tmp/out.txt</code>

再比如:将rclocal.txt檔案中包含“init”的行儲存為/tmp/out.txt檔案:

<code>[root@svr5 ~]</code><code># sed -n '/init/w /tmp/out.txt' rclocal.txt</code>

效果等同于:

<code>[root@svr5 ~]</code><code># sed -n '/init/p' rclocal.txt &gt; /tmp/out.txt</code>

2.sed的複制粘貼操作

1)基本動作指令

複制到剪貼闆:

H:模式空間 ---[追加]---&gt;保持空間

h:模式空間 ---[覆寫]---&gt;保持空間

讀取剪貼闆内容并粘貼:

G:保持空間 ---[追加]---&gt;模式空間

g:模式空間 ---[覆寫]---&gt;保持空間

若要實作“剪切”操作,實際上就是先“複制”再“删除”。

講一下sed的2個空間:

模式空間:

--存放目前處理的行,将處理結果輸出

--若目前行不符合處理條件,則原樣輸出

--處理完目前行再讀入下一行來處理

保持空間:

--作用類似于”剪貼闆“

--預設存放一個空行(換行符\n)

2)複制操作練習

還以rclocal.txt檔案為例:

将第rclocal.txt檔案的第1-3行内容複制到檔案末尾:

<code>[root@svr5 ~]</code><code># sed '1,3H;$G' rclocal.txt</code>

從上述結果可以發現,使用G粘貼操作的效果是追加。但是,檔案原内容與新追加的文本之間還有一個空行,這是怎麼來的呢?這是保持空間預設的内容“\n”,追加操作時就保留了。那麼,如果将G追加改為g覆寫來粘貼,結果會怎麼樣呢?看看:

<code>[root@svr5 ~]</code><code># sed '1,3H;$g' rclocal.txt</code>

什麼情況?把原檔案的最後一行給覆寫了。如果既要保留原檔案的所有内容,又想複制前3行到檔案末尾,而且不希望有空行分開,怎麼辦呢?把複制操作H追加改成h覆寫試試看什麼結果:

<code>[root@svr5 ~]</code><code># sed '1,3h;$G' rclocal.txt</code>

<code>1</code><code>#!/bin/sh</code>

<code>8 </code><code># This script will be executed *after* all the other init scripts.</code>

這下原檔案内容是保留了,空行也沒了,但是追加的内容卻隻有第3行,為什麼?

因為sed是逐行處理的,是以每次h覆寫操作都會清空原來存放在保持空間的文本,也就是說用h複制第1行到保持空間後,預設的“\n”就沒了;再用h複制第2行到保持空間後,前一次複制過去的第1行文本又沒了;再用h複制第3行到保持空間後,前一次複制過去的第2行文本又沒了,…… 于是,最終隻有比對的最後一行能夠成功添加。

總和上述分析,我們可以在複制第一行的時候用h覆寫,而以後的每一行用H追加,這樣就可以完美無空行的追加比對行了:

<code>[root@svr5 ~]</code><code># sed '1h;2,3H;$G' rclocal.txt</code>

3)剪切操作練習

将rclocal.txt檔案的第1-4行轉移到檔案末尾:

<code>[root@svr5 ~]</code><code># sed '1{h;d};2,4{H;d};$G' rclocal.txt</code>

将包含單詞“init”的行剪切到檔案末尾,保留預設的空行分隔:

<code>[root@svr5 ~]</code><code># sed '/\&lt;init\&gt;/{H;d};$G' rclocal.txt</code>

二、擴充

1.sed逐字元替換

sed的s操作可實作字元串替換,而另一個操作y操作可實作逐個字元替換。

什麼意思呢?對比一下:

's/OLD/NEW/g' ,處理方式為整串比對,隻比對完整的字元串“OLD”,對單個字元“O”、“L”或者“D”無效,而且替換前後的字元串長度可以不相同(比如,“OLD”可替換為“NEWNEW”)。實作的效果是——将文本中所有的字元串“OLD”替換為“NEW”。

'y/abcd/ABCD/',處理的方式為逐個字元依次替換,替換前後的内容必須一一對應、數量一緻。實作的效果是——将檔案内所有的字元“a”替換為“A”、字元“b”替換為“B”、字元“c”替換為“C”、字元“d”替換為“D”。

下面仍以rclocal.txt檔案為例,測試一下y操作的相關效果。

确認rclocal.txt檔案内容:

<code>.2 </code><code>#</code>

1)将所有的小寫字母i替換為大寫的I:

<code>[root@svr5 ~]</code><code># sed 'y/i/I/' rclocal.txt</code>

<code>1 </code><code>#!/bIn/sh</code>

<code>.3 </code><code># ThIs scrIpt wIll be executed *after* all the other InIt scrIpts.</code>

<code>4 </code><code># You can put your own InItIalIzatIon stuff In here If you don't</code>

<code>5 </code><code># want to do the full Sys V style InIt stuff.</code>

<code>.6</code>

等效于:

<code>[root@svr5 ~]</code><code># sed 's/i/I/g' rclocal.txt</code>

<code>3 </code><code># ThIs scrIpt wIll be executed *after* all the other InIt scrIpts.</code>

2)将所有的小寫字母a、e、l替換為大寫:

<code>[root@svr5 ~]</code><code># sed 'y/ael/AEL/' rclocal.txt</code>

<code>3 </code><code># This script wiLL bE ExEcutEd *AftEr* ALL thE othEr init scripts.</code>

<code>4 </code><code># You cAn put your own initiALizAtion stuff in hErE if you don't</code>

<code>5 </code><code># wAnt to do thE fuLL Sys V styLE init stuff.</code>

<code>7 </code><code>touch</code> <code>/vAr/Lock/subsys/LocAL</code>

等效于:

<code>[root@svr5 ~]</code><code># sed 's/a/A/g;s/e/E/g;s/l/L/g' rclocal.txt</code>

3)将所有的字元a變為數字1、字元e變為數字5、字元l變為變為字元X:

<code>[root@svr5 ~]</code><code># sed 'y/ael/159/' rclocal.txt</code>

<code>3 </code><code># This script wi99 b5 5x5cut5d *1ft5r* 199 th5 oth5r init scripts.</code>

<code>4 </code><code># You c1n put your own initi19iz1tion stuff in h5r5 if you don't</code>

<code>5 </code><code># w1nt to do th5 fu99 Sys V sty95 init stuff.</code>

<code>7 </code><code>touch</code> <code>/v1r/9ock/subsys/9oc19</code>

2.單詞的大小寫轉換

将比對結果轉大寫可用\U&amp;、轉小寫可用\L&amp;,這裡的&amp;為調用的比對串。

還以前面的rclocal.txt檔案為例,确認内容如下:

1)将所有的小寫字母轉為大寫:

<code>[root@svr5 ~]</code><code># sed 's/[a-z]/\U&amp;/g' rclocal.txt</code>

<code>1 </code><code>#!/BIN/SH</code>

<code>3 </code><code># THIS SCRIPT WILL BE EXECUTED *AFTER* ALL THE OTHER INIT SCRIPTS.</code>

<code>4 </code><code># YOU CAN PUT YOUR OWN INITIALIZATION STUFF IN HERE IF YOU DON'T</code>

<code>5 </code><code># WANT TO DO THE FULL SYS V STYLE INIT STUFF.</code>

<code>7 TOUCH </code><code>/VAR/LOCK/SUBSYS/LOCAL</code>

<code>[root@svr5 ~]</code><code># cat rclocal.txt | tr [:lower:] [:upper:]</code>

2)将所有的大寫字母轉為小寫:

<code>[root@svr5 ~]</code><code># sed 's/[A-Z]/\L&amp;/g' rclocal.txt</code>

<code>3 </code><code># this script will be executed *after* all the other init scripts.</code>

<code>4 </code><code># you can put your own initialization stuff in here if you don't</code>

<code>5 </code><code># want to do the full sys v style init stuff.</code>

<code>[root@svr5 ~]</code><code># cat rclocal.txt | tr [:upper:] [:lower:]</code>

3)将每個單詞的首字母大寫:

<code>[root@svr5 ~]</code><code># sed -r 's/\b[a-Z]/\U&amp;/g' rclocal.txt</code>

<code>1 </code><code>#!/Bin/Sh</code>

<code>3 </code><code># This Script Will Be Executed *After* All The Other Init Scripts.</code>

<code>4 </code><code># You Can Put Your Own Initialization Stuff In Here If You Don'T</code>

<code>5 </code><code># Want To Do The Full Sys V Style Init Stuff.</code>

<code>7 Touch </code><code>/Var/Lock/Subsys/Local</code>

4)将每個單詞的首字母大寫,其餘字母小寫:

<code>[root@svr5 ~]</code><code># sed -r 's/([a-Z])([a-Z]+)/\U\1\L\2/g' rclocal.txt</code>

<code>4 </code><code># You Can Put Your Own Initialization Stuff In Here If You Don't</code>

總結:

1、若要實作“剪切”操作,實際上就是先“複制”再“删除”。

2、因為保持空間預設會有一個換行符号,是以把模式空間的内容放到保持空間的時候,第一行用h覆寫來把換行符給覆寫掉,這樣就不會出現一行空格

      本文轉自Jx戰壕  51CTO部落格,原文連結:http://blog.51cto.com/xujpxm/1391849,如需轉載請自行聯系原作者

繼續閱讀