2015年4月9日 星期四

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

原文: 原文在此

== 結論的好方法 ==
情境 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' {}

最後會當掉。

1 則留言:

  1. Okay then...

    This may sound kind of weird, maybe even kind of "out there"....

    WHAT if you could simply press "Play" to LISTEN to a short, "magical tone"...

    And INSTANTLY bring MORE MONEY into your life??

    And I'm talking about hundreds... even thousands of dollars!!

    Sound too EASY?? Think it's IMPOSSIBLE?

    Well, I'll be the one to tell you the news..

    Usually the most significant blessings life has to offer are the EASIEST!!

    Honestly, I'm going to PROVE it to you by allowing you to listen to a real-life "magical abundance tone" I developed...

    YOU simply push "Play" and watch as your abundance angels fly into your life. starting pretty much right away.

    GO here now to PLAY the magical "Miracle Abundance Sound Frequency" as my gift to you!!

    回覆刪除