搜尋並取代 某些文件裡面的 某個字串 - Linux

Suhail Hany avatar
By Suhail Hany
at 2009-10-21T20:09

Table of Contents


http://liwecan.pixnet.net/blog/post/29606145


== 結論的好方法 ==

情境 ex1:將資料夾內 case01.conf ~ case99.conf 裡的

senor 錯字改成 sensor



find *.conf | xargs -i sed -i 's/senor/sensor/g' {}


find *.conf 會找資料夾內的 .conf 檔,

即情境中的 case01.conf ~ case99.conf,輸出為 99 行;


| 是 pipe 指令,能將前者的 standard output,

作為後者的 standard input 繼續處理;

(這裡有兩個 point,一是前一個指令的 standard error 會被忽略,

二是後一個指令必需是處理 standard input 的指令)


xargs 的目的,是用來將所得的結果參數化,

即我們會將前者的 standard output,當作接下來指令的某個參數。

其中,透過 xargs -i {},

我們可以將前者 n行輸出的每一行,視為一次輸出,

將其擺至 {} 的位置,而得到 n 次輸入執行 n 遍。

(若不使用 xargs -i {},則會把前面 n行的 output 一次全丟給後者)


也就是說

find *.conf | xargs -i sed -i 's/senor/sensor/g' {}

至此會等同於

sed 's/senor/sensor/g' case01.conf

sed 's/senor/sensor/g' case02.conf



sed 's/senor/sensor/g' case99.conf


而 sed 的格式是

sed 'command' filename,

command 跟 regular expression 有關,

總之,這個例子的意思是,

尋找 filename 檔案中的所有 senor 字串,並取代為 sensor 字串。


情境 ex2:1test1、1test2 … 24test5、24test6 內,

有些字串是 2.6.16,有些是 2a6b16,

欲將 2.6.16 改為 2.6.28


find *test* | xargs -i sed -i 's/2\.6\.16/2\.6\.28/g' {}


ex2 的寫法在底下對 vim 的討論有詳細的解釋,


== 對單一檔案的解法 ==

假設要將 filename 檔案裡的 2009 改成 2010


vim 解法 (後面有詳細的討論,與不知如何解的問題)

vim -c '1,$s/2009/2010/g' -c ':wq' filename

或是 vim 檔案後,直接按 :

輸入 1,$s/2009/2010/g 的指令。


sed 解法 (速度快,效果好)

sed -i 's/2009/2010/g' file

有新版的 GNU sed 即可用上面的解法,

舊版的可能要

sed 's/2009/2010/g' oldfile > tmpfile; mv tmpfile oldfile


perl 解法 (我不懂 perl,還不會讓其搜尋檔案並操作)

1. 建 xxx.pl 檔,寫一行指令,

2. perl -pi -e "s/2009/2010/g" filename

3. chmod 755 xxx.pl 使其可執行後,

4. 下 ./xxx.pl 執行


== 舊的 vim 的討論 ==

目的:

把 fullset-k26.mak 裡的 2.6.16 全部取代成 2.6.28

指令:

vim -c ':1,$s/2\.6\.16/2\.6\.28/g' fullset-k26.mak


== vim 的 解釋 ==

vim -c command file


這裡有兩個部份要注意,

一個是 "vim -c command file" 整段是 command line 的命令,

有些特殊字元在 command line 有別的意義,

另一個是 "command" 本身是要傳給 vim 的命令,

要符合 regular expression 的用法。


因為 command line 中, $ 會被視為呼叫變數,

所以需用 \$ 或是 '$' 來表示 $ 是傳給 vim 的 regular expression

(在 reqular expression 中, $ 代表 檔尾 or 行尾,

例如 1,$s/x$/l,第一個$是檔尾,第二個$是行尾)

在此是整串 command 都用 ' ' 括住比較方便 (因為後面還有 . 要注意)


在regular expression的 . 代表非斷行的任意字元

所以為了確保不會有 2a6b28 被取代掉,

所以在 vim 的 command 中要用 \. 來表示是 2.6 而非 2a6 之類的任意字元


而在 command line 中,應該用 \\. 或是 '\.' 代表要傳 \. 給 vim

(如果是 \.,會把 \ 忽略認為要傳 . 給 vim,vim 會認為 . 代表任意字元

所以是 \\. ,認為要傳 \. 給 vim,讓 vim 找 . 這個字元)


也就是上述的命令等同於

vim -c :1,\$s/2\\.6\\.16/2\\.6\\.28/g fullset-k26.mak


不過,還是用括號括比較方便

也就是一開頭的

vim -c ':1,$/2\.6\.16/2\.6\.28/g' fullset-k26.mak


然後,不再接一個 -c ':wq' 的指令,

他會把檔案開啟來,並把 2.6.16 取代成 2.6.28 後,仍未存檔,

好處是可以檢查無誤後再存檔。


== vim 的 問題 ==

與 find *.conf | xargs -i {} 合在一起用時,如:

find *.conf | xargs -i vim -c '1,$s/senor/sensor/g' -c ':wq' {}

最後會當掉。


--

--

--
Tags: Linux

All Comments

Skylar DavisLinda avatar
By Skylar DavisLinda
at 2009-10-26T07:31
感謝~ 連兩篇分享的內容面都很實用,值得一看~

使用pietty呼叫gui程式

Madame avatar
By Madame
at 2009-10-21T19:42
想要用pietty呼叫一些有gui的程式 並不是在windows視窗出現, 而是在remote端執行 但是當我打下amule 卻顯示 Error: Unable to initialize gtk, is DISPLAY set properly? 嘗試著google卻沒找到解法 麻煩知道如何操作的版友講 ...

如何讓linux自動sleep/reboot 500次

Hedwig avatar
By Hedwig
at 2009-10-21T19:19
我也來改一下,(本人超弱的) #!/bin/bash # 計算次數 if [ -x /home/count.txt ]; then count=1 else count=`cat /home/count.txt|wc -l` fi # 測試 if [ $count -lt ...

首次登入系統FC圖形介面安裝完當機

Zora avatar
By Zora
at 2009-10-21T18:14
我買鳥哥的書,基礎學習第二版 我從第一章看到第四章才跟鳥哥書一起安裝的 我家電腦是買宏碁產品M35的桌上型電腦, 我的是 AMD athlon(tm) 64 processor 3200+ 2.21GHz,512MB的RAM 顯示卡是NVIDIA FX5500 我用鳥哥書上附的FC4光碟安裝 我把平 ...

Cygwin 中的 Vim

Charlie avatar
By Charlie
at 2009-10-21T17:44
請問有辦法套用 colorscheme 嗎? 我按照網路上的作法下載 colorscheme 並更改 .vimrc 可是都沒有辦法成功, 想請教一下該如何正確設定 或是在 cygwin 底下,vim 的顏色就註定只能是黑白? - ...

IIS on Linux?

Frederic avatar
By Frederic
at 2009-10-21T09:23
剛剛用 netcraft 查某網站的server 居然有 and#34;http://www.xxx.xxx.tw was running Microsoft-IIS on Linuxand#34; IIS 有出 Linux 版本嗎? - ...