[转]VI 指令详解

转]VI 指令详解 引用并回复

使用 vi 如何以簡單有條理的方式來重複處理檔案中的資料,並在不更動原檔案的情況下,將這些資料存放到新檔案中?

嚴格說來,這樣的處理作業,應選擇像 sed,awk 這樣的工具,在處理效率上比較好;如果,處理需求單純的話,grep 也足以應付。但那樣的選擇,通常是在處理流程已經相當成熟,且有必要經常性的重複使用之下,所做的工具選擇。在突發性且處裡模式尚未釐清前,使用 vi 是較具彈性的選擇。

我以一個整理 httpd access_log 來作說明。

2001/12/16 凌晨,我剛好在主機上做點測試。當時的網路有點忙,我使用 netstat -ct 看了一會兒網路的狀況,知道目前 httpd 有幾位訪客。一時興起想看看她們來看什麼,於是我使用 vi 去看了一下 Apache 的 access_log,意外地發現,同一時間,我的同胞 202.102.141.56 正在掃描主機的 httpd server。再觀察一下 netstat -ct 的訊息,我發覺她還沒有完全做完。心想不應該打斷人家的工作。當時人已有點睏了,所以我退出了 vi 並趕緊繼續做我的事情。不久,周公他老人家就來抓我出公差,做他最近經營的 playboy 網站。虛擬實境的歐,採會員制,非十八歲以下的夢遺才俊不收。我只有做苦工的份,沒資格加入。

隔日自然醒來,打開電腦,先來上一段 Queen 的 We are the champions 加上一杯咖啡。突然想起凌晨未完成的觀察,馬上用 vi 再查看 access_log。乖乖!不是一個,前後共三位青年才俊上網。此時在 vi 模式下,我想分別將三位的資料從 access_log 檔案中分離出來,建立三個個別檔案。這種想法,以前不曾想過!一時卡住了,不知道該怎麼做?拿起筆來,在紙上寫下了"如何"挪移"這幾個字。喝完我的咖啡後,趴在桌上小咪一下..才一下,就被周公槌醒,我看著"挪移"兩字,方法找到了。

# vi access_log

我使用 vi 指令進入了要編輯的 access_log 檔案中。因為沒有加上任何特殊選項,所以游標會在第一行的位置。接著,我打算將有為青年一號,位址是 202.102.141.56,所遺留的拜訪紀錄全部挪移到檔案的最末端。指令如下:

:g/202.102.141.56/mo$

該行指令其中 g 代表 global,是整個檔案的意思。在 :g/ 後面的是要搜尋的字串,我代入的是 202.102.141.56,也就是有為青年一號。最後 mo$ 其實是 ex 編輯器的指令,mo 是 move 搬移;$ 則代表最後一行的意思。所以這行指令做的就是,將檔案從上到下檢查內含有 202.102.141.56 的每一行,找到了就將該行搬移到檔案的最後一行。執行完畢後,游標會停留在最後一行。

這樣,我就達到將"有為青年一號"的拜訪資料透析出來的目的了。當然,我是可以繼續使用相同的手法整理有為青年二、三號,不過我的想法是單獨存檔,所以這時還不需要處理。緊接著我要刪除無關的資料。

:/202.102.141.56

因為游標已在最後一行,搜尋會自動跳回第一行重頭開始尋找字串。藉此,我已將游標移動到"有為青年一號"資料的開頭位置。游標以上的是我不需要的資料,以下則是打算存檔的內容。

接著我將游標往上跳一行(也就是按一下 k 鍵),然後清除該行到第一行的所有資料。

d1G

清除後留下的就是"有為青年一號"全部資料。

:w Timmy-no1

將現存的結果另存新檔,檔名為取作 Timmy-no1。(Timmy 一字,來自於艾西莫夫與席維伯格合著的某本科幻小說,是一位非常特殊的主角)

到此,事情算到一個段落。因為我還要原來的資料,在一般狀況下,我會選擇 :q! 放棄存檔並退出 vi 。但因為我還需繼續透析出"有為"青年二、三號"的資料。所以我得回復原檔案的資料,簡單如下

:e!

這個動作,我個人比較喜歡稱為"倒帶"。好了,倒完帶後,檔案的內容就回復到上次存檔的狀態,我因為沒存過檔,所以便回復到進入 vi 時的原資料,接著就可以用先前的做法處理"青年二、三號"了。最後記得用 :q! 退出 vi 就可以了。

做完這件事之後,我滿足地睡個回籠覺。夢裡,周公對我說:幹的好呀,孩子。別忘了睡醒後把新會員的資料,E-mail 給我呦。下回嘉獎你享受一下"虛擬實境"的滋味。現在白天,既然來了,就好好地加班,建網頁去.....,還不快去!


傳統的 vi 指令,不支援多重視窗編輯。所以無法用一隻 vi 程式同時開啟兩個檔案做資料交換、轉移的編輯。但這點並沒有太大的不便,因為替代的方法也很簡單。只要善用 vi 程式的具名緩衝區,先將 A 檔案的資料暫存起來,然後繼續編輯 B 檔案,再呼叫出來即可。

對 vi 程式的運作而言,使用 d (delete) 與 y (yank) 都會將資料放入具名的 buffer 中。但對本文的需求來說,我自己絕對不會選擇 delete 來做,雖然做得到,但太危險。所以唯一且正確的選擇是使用 yank。她支援小寫字母 a ~ z 命名的具名緩衝區供使用者運作。現在仔細想想,似乎我從不曾嫌過 26 個不夠用?但她畢竟是一個相當有限的限制。

接下來是我實際運作的例子。每天系統的 message 檔案,總會有一些異常的信息。這些訊息雖多半具有規律性,但仍然會有無法掌握的情況出現。由於我的系統服務非常單純,所以我習慣使用 vi 查看每天發生的事情。檢視的過程中如果有異樣或自己搞不清楚的警訊,我就先將她存入具名緩衝區中,等到全部檢視完畢後,再決定如何處理。

現在,假設我要開始檢視 messages 檔案中有關於 12 月 24 日的紀錄;

# vi +/"Dec 24" messages

游標會停在我要的第一筆資料上。我往下檢視當天紀錄,不久發現連續三行資料有異樣,我把游標停在第一行的位置,下指令先將她們放入具名緩衝區中;

"q3yy

如此,三行資料就會存入 q 緩衝區內。再往下檢視,又發現零散的幾行異常都與某 IP 有關。因此我將 IP 的資料。一樣我先將游標停在該 IP 的開頭位置,然後再下指令;

"w8yw

該行的意思是存 8 個"字"(word)存到 w 緩衝區內。xxx.xxx.xxx.xxx 是 IP 的固定格式,其中的 dot 在定義上是特殊符號,視同一個"字"(word),所以像 IP 這樣的格式在表示上用 8 個"字"(word)。

往下再找到的,我都以相似的方法將她們存在不同的緩衝區內。最後我呼叫我自己的異常紀錄檔案,準備將資料儲存起來;

:e + strange2k112

在呼叫時我加上選項 "+",所以我游標會停來在最後一行。我開始順序地將存放在具名緩衝區的資料 put 到 strange2k112 這個檔案中;

"qp
"wp
"ep
....


小寫的 p 會將資料放在游標之後;想放在游標之前使用大寫的 P 即可。


在編輯的過程中,早已刪除的資料,突然想再找回來。這樣的事情難免會偶而發生。有人會選擇一路 undo 回去,甚至完全放棄所有的編輯,我個人並不認為這是好的做法。因此如過可能的話,我還是想找回來,如果找得回來的話。要想這樣做,首先就必須清楚,vi 程式是如何處理 delete 的資料。

vi 程式規劃了 9 個具名緩衝區供 delete 做資料暫存。緩衝區的名稱就是數字 1 到 9。資料採"先進先出"的模式存放。也就是說,你清除一筆資料,它會被放入緩衝區 1,原先緩衝區 1 內的資料會被新進的資料擠到緩衝區 2,以此類推,可以想像,緩衝區 8 的資料擠進緩衝區 9 後,原先緩衝區 9 的資料將會被丟棄。而被丟棄的資料,將無法使用呼叫具名緩衝區的方式挽救回來。

清楚其運作方式後,你將發現,要明確地掌握資料在哪一個緩衝區內,實在是一件高難度的事情!原因在清楚不過,誰會去記這碼事?就算有人刻意去記恐怕也不是一件輕鬆的事。坦白說,打死我,我也不會去記!

所以萬一事情發生了,想使用這個方法找回來,心裡必須有數,只有九個緩衝區,可不可能還在?如果可能的話再用。得用上時,土法煉鋼的方法是,由呼叫緩衝區 9, 8, 7...一路找,

"9p
"8p
"7p
"6p
"5p
"4p
"3p
"2p
"1p


當然,順序也可以反過來啦!但方法實在不是普通的難看。如果旁邊有人,有可能導致一世英名毀於一旦。所以做這件事情的時候,得用比較好看一點的姿勢來做。

首先,我先說明,這個方法,是由數字小到大呼叫緩衝區。無法由大到小。呼叫的第一個緩衝區,可以不必由緩衝區 1 開始,可以是其他數字。我個人因腦袋長得比較小,年紀也比較大,所以我習慣從頭開始,

"1p

出現的當然毫無疑問地是最後一次。然後,

u.

打 u 是 undo 的意思,螢幕上緩衝區 1 的資料會消失。而 dot (.) 是 repeat 的意思。效果相當於呼叫下一個緩衝區的資料,所以緩衝區 2 的資料會顯示出來。想再看下一個緩衝區,就再打一次 u. 就可以了。

如果無法在數字緩衝區找回資料,只要在還未存檔的的情況下,我會將現狀另存新檔,然後回復原編輯檔案的資料,搜尋到資料後,放在具名的緩衝區內,再編輯剛剛另存的新檔即可。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值