== 結論的好方法 ==

情境 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' {}

最後會當掉。


--

創作者介紹

Yes, WeCan!分享生活

LiWeCan 發表在 痞客邦 PIXNET 留言(0) 人氣()