awk & sed ,一個老派系統管理員的基本素養
圖片來源: Shutterstock
我們不要讓下一代 Linux 和 Unix 的管理員忘記初始化腳本和基本工具的好處
我曾經有一次在 Reddit 看到一個帖子,「請問如何操作文本文件」。這是一個很簡單的需求,就像我們常用 Unix 的人每天遇到的一樣。他的問題是,如何刪除文件中的重複行,只保留不重複的。 這聽起來似乎很簡單,但是當文件足夠大時,就會有些複雜。
這個問題有很多種不同的答案。你可以使用幾乎任何一種語言來寫這樣的一個腳本,只是時間的投入和代碼的複雜性不同罷了。根據你的個人水平,它大概會花費20-60分鐘。但是如果你使用了 Perl、Python、Ruby 中的一種,你可能很快實現它。
或者你可以使用下面的一個方法,讓你無比暖心的: 只用 awk。
這個答案是迄今為止最簡明、最簡單的解決問題的方法。它只要一行!
awk '!seen[$0]++' <filename>
讓我們來看看發生了什麼:
在這個命令中,其實隱藏了很多代碼。awk 是一種文本處理語言,並且它內部有很多預設。首先,你看到的實際上是一個 for 循環的結果。awk 假定你想通過循環處理輸入文件的每一行,所以你不需要明確的去指定它。awk 還假定了你需要列印輸出處理後的數據,所以你也不需要去指定它。最後,awk 假定循環在最後一句指令執行完結束,這一塊也不再需要你去指定它。
這個例子中的字元串 seen 是一個關聯數組的名字。$0 是一個變數,表示整個當前行。所以,這個命令翻譯成人類語言就是「對這個文件的每一行進行檢查,如果你之前沒有見過它,就列印出來。」 如果該關聯數組的鍵名還不存在就添加到數組,並增加其取值,這樣 awk 下次遇到同樣的行時就會不匹配(條件判斷為「假」),從而不列印出來。
據微博上 [@ZorroLang](http://weibo.com/3246109510 "ZorroLang") 的補充:少提了一個重點,要不然只會 C 語言的人很難理解為什麼 seen[$0]++ 一行代碼就行了,這裡隱含了 awk 對於其數組變數的處理方式。awk 的數組是關聯數組,且不需要聲明,而是引用即創建,注意是創建,後面都不會消失的。也就是你像 str[any] 這樣隨便寫一個數組變數,這個數組元素就此就創建了,且初始化為0或空。
謝謝 [@ZorroLang](http://weibo.com/3246109510 "ZorroLang") ~
一些人認為這樣是優雅的,另外的人認為這可能會造成混淆。任何在日常工作上使用 awk 的都是第一類人。awk 就是設計用來做這個的。在 awk 中,你可以寫多行代碼。你甚至可以用 awk 寫一些讓人不安的複雜功能。但終究來說,awk 還是一個進行文本處理的程序,一般是通過管道。去掉(沒必要的)循環定義是很常見的快捷用法,不過如果你樂意,你也可以用下面的代碼做同樣的事情:
awk '{ if (!seen[$0]) print $0; seen[$0]++ }』
這會產生相同的結果。
awk 是完成這項工作的完美工具。不過,我相信很多管理員--特別是新管理員會轉而使用 Bash 或 Python 來完成這一任務,因為對 awk 的知識和對它的能力的了解看起來隨著時間而慢慢被人淡忘。我認為這是標誌著一個問題,由於對之前的解決方案缺乏了解,那些已經解決了幾十年的問題又突然出現了。
shell、grep、sed 和 awk 是 Unix 的基礎。如果你不能非常輕鬆的使用它們,你將會被自己束縛住,因為它們構成了通過命令行和腳本與 Unix 系統交互的基礎。學習這些工具如何工作最好的方法之一就是觀察真實的例子和實驗,你可以在各種 Unix 衍生系統的初始化系統中找到很多,但在 Linux 發行版中它們已經被 systemd 取代了。
數以百萬計的 Unix 管理員了解 Shell 腳本和 Unix 工具如何讀、寫、修改和用在初始化腳本上。不同系統的初始化腳本有很大不同,甚至是不同的 Linux 發行版也不同。但是它們都源自 sh,而且它們都用像 sed、awk 還有 grep 這樣的核心的命令行工具。
我每天都會聽到很多人抱怨初始化腳本太「古老」而且很「難」。但是實際上,初始化腳本和 Unix 管理員每天使用的工具一樣,還提供了一個非常好的方式來更加熟悉和習慣這些工具。說初始化腳本難於閱讀和難於使用實際上是承認你缺乏對 Unix 基礎工具的熟悉。
說起在 Reddit 上看到的內容,我也碰到過這個問題,來自一個新入行的 Linux 系統管理員, 「問他是否應該還要去學老式的初始化系統 sysvinit」。 這個帖子的大多數的答案都是正面的——是的,應該學習 sysvinit 和 systemd 兩個。一位評論者甚至指出,初始化腳本是學習 Bash 的好方法。而另一個消息是,Fortune 50 強的公司還沒有計劃遷移到以 systemd 為基礎的發行版上。
但是,這提醒了我這確實是一個問題。如果我們繼續沿著消除腳本和脫離操作系統核心組件的方式發展下去,由於疏於接觸,我們將會不經意間使新管理員難於學習基本的 Unix 工具。
我不知道為什麼有些人想在一層又一層的抽象化來掩蓋 Unix 內部,但是這樣發展下去可能會讓新一代的系統管理員們變成只會按下按鈕的工人。我覺得這不是一件好事情。
via: http://www.infoworld.com/article/2985804/linux/remember-sed-awk-linux-admins-should.html
作者:Paul Venezia 譯者:Bestony 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive