如何在linux下快速替換多個文件的文本?

    哥現在參與的產品無比龐大,每次部署環境,都要修改無數配置文件,讓開發/測試尤其是去客戶現場實施的人員頭疼不已.據粗略估計,有數十個模塊,每個模塊下面一個配置文件,模塊之間藕斷絲連,有着難以割捨的關係--當然,如果不該割的割了,就要出大問題了,你懂的--,這其中,配置文件起着決定性的調度作用,模塊與模塊的溝通協作,可以說,是靠着配置文件實現的.
    問題是什麼呢?由於需要去不同的客戶處安裝我們的系統,而每個客戶的具體環境又是不同的,諸如IP,端口等基本設置就要進行批量修改,如果沒有合適的工具或命令幫我們完成這件事情,該是多麼痛苦的體力活啊!當然了,我們可以在windows下用UE或神馬編輯器批量打開所有配置文件(*.ini),然後全文替換,但是一般情況下我們是需要在客戶處現場修改的,想想一種場景:當一切就緒,準備把所有安裝包上傳到服務器安裝之前,先對客戶說:稍等!我需要知道你們機器的ip,我現在windows下改好再上傳安裝..客戶此時的表情該有多麼古怪..在客戶眼裏,你被想當然賦予一個無敵的角色,任何問題都是可以解決的,所以..經歷過用VI一個一個打開配置文件修改IP的本人來說,必須痛下決心解決這個問題.
    首先,假設我們只有3個文件(無論多少都大同小異哈),a.ini,b.ini,c.ini,他們在磁盤中存放的位置關係如下:

    base-dir/
            /------1/
                   /-----11/
                         /------a.ini
                   /-----12/
                         /------b.ini
            /------2/
                   /------------c.ini

    三個文件的內容類似,以a.ini舉例:

        $ cat a.ini

        [a.ini]
        SELF_IP=10.253.46.98:6008
        NODE_ID=50001
        SERVER_IP=10.253.46.97:6007
        ...

    我們的目標是替換掉每個a.ini的SELF_IP爲192.168.14.38
    先說解決辦法:


        # 切換到包含所有待修改文件的根目錄
        $ cd base-dir  

        # 用find命令過濾所有待修改文件,然後調用sed行編輯器批量替換
        $ find ./ -name *.ini -exec sed -i "s/10.253.46.98/192.168.14.38/g" {} /;

        # 看一下是不是都改好了
        $ find ./ -name *.ini -exec grep -H 'SELF_IP=' {} /;
        ./1/11/a.ini:SELF_IP=192.168.14.38:6008
        ./1/12/b.ini:SELF_IP=192.168.14.38:6008
        ./2/c.ini:SELF_IP=192.168.14.38:6008

        # 如果還是不放心,再確認一下
        $ find ./ -name *.ini -exec grep -H '192.168.14.38' {} /;      
        ./1/11/a.ini:SELF_IP=192.168.14.38:6008
        ./1/12/b.ini:SELF_IP=192.168.14.38:6008
        ./2/c.ini:SELF_IP=192.168.14.38:6008
        # 大功告成

    有關解釋:
    上例中我們使用了三個主要命令:find,sed和grep.由於都是很常見的命令,我就不把man手冊對它們的詳細用法翻譯過來咯,只對本例的用法稍作解釋,已經對這個小技巧了熟於胸的童子可以略過後面的內容.
    1.find ./ -name *.ini -exec sed -i "s/FROM/TO/g" {} /;
    這句話的含義是在當前目錄(./)查找名字(-name)匹配*.ini的所有文件,然後將這個結果集合傳遞給(-exec是execute簡稱)sed 進行處理,後面的{} /;是固定格式.sed -i "s/FROM/TO/g" filename 表示對給定文件進行全局替換(g保證了這一點,如果不加g,那麼如果同一行有多個匹配,只會替換第一個),查找FROM字符串替換爲TO字符串,-i參數表示即時修改(in-place),如果不加的話,也會替換掉相應內容,但不會修改文件本身,結果是在屏幕輸出替換後的文件內容,可以重定向到其他地方保存起來,有點類似於"另存爲"的概念.
    2.find ./ -name *.ini -exec grep -H '192.168.14.38' {} /;
    類似的,這句話是說查找所有*.ini的內容中有無匹配字符串'192.168.14.38'的行,如果有,連同文件名(-H參數)一起打印出來.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章