當前位置:
首頁 > 科技 > 程序員,你真的會用 Unix 命令?

程序員,你真的會用 Unix 命令?

那些常用的 Unix 命令,你不知道的功能!

作者 | Vegard Stikbakke

譯者 | 彎月

責編 |屠敏

出品 |CSDN(ID:CSDNNews)

以下為譯文:

我逐漸意識到,Unix 的命令行工具可以解決一切與文字處理有關的問題。我來講一個我遇到過的問題,以及怎樣用 Unix 命令行工具解決的。

問題

我在做我的碩士論文研究。像許多統計學家一樣,我需要進行許多模擬。首先我利用一些數字的種子(以保證可復現性)來模擬了一些數據,然後在這些數據上用一個演算法來估算一些東西。每次運行模擬時我都會創建一些文件,大概像下面這樣:

但有時候運行會失敗。這並不是太嚴重,模擬失敗了我只需要運行另一個模擬就好了。比如,0001 這個數據我成功地運行了演算法 A。因此我想在 0001 數據上使用演算法 B。但我真正需要的是跟蹤哪些命令失敗了。

在許多數據上運行演算法 A 之後,我得到了一大堆文件,像這樣:

通過觀察得知演算法 A 在數據 0004 和 0008 上的結果不存在。那麼,怎樣才能列出所有 A 沒有成功的數據呢?

我當然可以手工來做,但那樣很容易出錯,而且很麻煩。要是能寫程序完成就最好了!

解決方案

簡單地來說,那些沒有成功的就是從0001到0500的數字中去掉那些成功了的數字。而得到數字列表的最好命令就是 seq:

(如果只給出一個數字,那麼默認序列從1開始。當然,seq 2 10也會按照你期待的那樣工作。)

現在,如果我能獲得成功運行的列表,就可以通過 seq 命令生成所有可能的數字,再交叉檢查兩個列表來獲得想要的結果了!

許多命令行工具只完成一項工作。例如,cut 可以獲得每行指定位置上的字元:

注意這裡使用了所謂的「管道運算符」 | 。我說過,許多工具只做一件事,而且把那件事做到最好。很方便的是這些工具可以組合使用。使用管道,左邊命令的結果就會變成右邊命令的輸入。注意這些命令會將輸入當做一系列行來處理,通常來說這非常方便。

我們可以把成功的文件名單列表利用管道輸入至 grep 命令,該命令可以使用正則表達式來查找。由於所有文件都以同樣長度的四個數字開始,我們可以利用正則表達式 dddd 來匹配這四個連續的數字,然後將文件末尾的 A 演算法加到正則表達式中。要獲得文件列表,每行一個文件,只需執行 ls。(儘管直接調用 ls 時並不會顯示成每行一個文件,但放在管道中時輸出就會變成這樣。)

出於某些原因,在使用 grep 之後這裡的順序混亂了。我們可以使用 sort 命令來改正。而且由於我們只關心數字,可以使用 cut -c 1-4 來取出數字部分。

這些數字跟 seq 命令的結果不太一樣,因為它們前面補了零。我們可以使用一段 Python 腳本將它們轉成整數。

現在將結果用管道導入這個腳本就能得到我們需要的數字:

接近目標了!現在需要找出怎樣才能交叉檢查這兩個數字的列表。幸運的是,有個命令叫做comm,它能檢查兩個輸入流中的公共字元。為了將上面這個命令的輸出作為輸入使用,我們可以將其求值後重定向,只需使用

這個輸出不是太好理解。閱讀 comm 的手冊(運行 man comm)可以發現,comm 會「產生三列的輸出,分別是:只存在於 file1 的行,只存在於 file2 的行,以及存在於兩個文件的行」。要去掉第一列(其實它是空的,因為沒有任何數字只存在於文件列表中),可以在調用 comm 時加入參數-1。我們也不關心同時存在於兩個輸入中的數字,因此還要傳遞標誌-3。

搞定!

網友說

這個方法發布之後,在 Hacker News(https://news.ycombinator.com/item?id=19160659)上引發無數網友參與討論:

評論 1:

Unix CLI 工具最有意思的地方在於有數百萬種有效的方法來解決問題。我還想到了我自己的「更好」的解決方案,跟這裡說過的大多數方法完全不同的方法。但這不是重點。

這篇文章的優點在於它遵循逐步解決問題的過程。我發現很多與我一起工作的程序員都在努力解決 CLI 問題,我覺得這有點令人驚訝。但我認為這完全取決於你如何看待這樣的問題。

如果你從「我如何構建一個函數來操作這個原始數據?」或「哪種數據結構最能表達這些文件名之間的關係?」那麼肯定會遇到困難。但是,如果你考慮「如何改變這些數據以消除無關的細節?」和「我有什麼工具可以解決數據上的問題,如果有一些麻煩,我怎麼能解決這些麻煩?」並且如果能接受採用逐步的方式,而不是構建和操縱整個抽象邏輯結構,那麼你就可以有效地利用這些工具在幾分鐘之內解決這些問題,無需花費幾小時。

評論 2:

這篇文章的問題是:「cut」命令後的參數並沒有什麼標準格式。

更糟糕的是,看似有標準格式,其實被許多其他格式破壞了。通常,這些格式取決於最初的作者,以及當時人們流行的想法。所以,有時候標誌會「聚集」在一起,同時假設多字元的標誌會使用兩個橫線作為開始。後來一些程序開始用一個橫線來表示多字元的標誌。還有許多其他的不一致。如果我學習了cut的基本範圍語法,我能知道 imagemagick 的基本語法嗎?

這些不一致在技術上並不衝突,因為每個只存在於特定的背景下。但是,如果看到那些不一致的東西被放在管道兩側,特別是當其中一個是非標準用法時,理智上真的很痛苦。 (或者,即使它只是你需要的一個命令,但是你使用了錯誤的標誌語法。)這一切都增加了認知負荷。

哦,從 Bash 轉到 Python 語言是一個巨大的風險。如果你每天使用 Python 編寫腳本,那可能還問題不大。但對於讀者來說,語言邊界是巨大的。因為用戶不僅需要處理運行時錯誤和格式錯誤,而且還需要處理語言錯誤。如果命令行跳出一個語法錯誤或異常,我相信大多數讀者就不會再讀下去了。

原文:http://vegardstikbakke.com/unix/

本文為 CSDN 翻譯,如需轉載,請註明來源出處。

【End】

熱 文推 薦

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CSDN 的精彩文章:

TIOBE 2 月編程語言排行榜:Python 逼近 C,Groovy 重回 TOP20
漫畫:什麼是 HTTPS 協議?

TAG:CSDN |