2011-01-26 45 views
5

我發現下面的腳本上commandlinefu.com(例子中是不在線了):這個bash函數是如何移除除了一些文件之外的所有文件的?

rmbut() { 
    local x=("[email protected]") 
    IFS=, rm -rf *[!"${x[*]}"] 
} 

它刪除所有的文件和目錄,但指定的命令行上的人。

你能解釋下:

  • 什麼是第一行發生了什麼? [email protected]表示所有參數,但它爲什麼放在圓括號內?
  • 我已閱讀關於IFS但從未實際使用過它,它在這裏有什麼用處?
  • *[!"${x[*]}"]實現了什麼?我無法理解如何將它分解成我知道的東西。
+0

你確定那些是「local x ..」行上的括號(),或者它們是大括號{}或括號[]。它有所作爲。另外,從函數的外觀來看,它只是刪除除函數參數指定的基本名之外的所有文件。 – kvista 2011-01-26 13:48:34

+0

是的,括號是正確的。這是函數的目的,很明顯,我想知道爲什麼^^ – 2011-01-26 14:00:18

回答

4

local x=("[email protected]")創建一個陣列,其是所有參數的副本([email protected]本身就是一個數組)。

IFS=,將內部字段分隔符設置爲逗號。

IFS=, rm -rf *[!"${x[*]}"]表示刪除所有不以任何字符結尾的文件作爲參數傳遞。由於*被用作數組的索引並且變量被引用,所以它被擴展爲單個字符串,並且通常將數組元素分隔的空格被IFS(在這種情況下爲逗號)的內容替換。

rmbut a b c 

解決爲rm -rf *[!a,b,c]這也不會刪除以逗號結尾的文件。

認爲功能可以簡化爲:

rmbut() { 
    IFS= rm -rf *[!"$*"] 
} 

,但它的行爲會稍有不同。此版本將IFS設置爲空,因此上述示例將解析爲rm -rf *[!abc],其中刪除以逗號結尾的文件(逗號將不得不作爲參數顯式傳遞以保留此類文件)。但是,該行爲可以通過設置IFS=,(它根本不需要複製數組)來返回。

3

#創建的數組x,包含函數的自變量
local x=("[email protected]")

#取消設置IFS變量。這使得雙引號陣列擴展到單個字的w/o隔板
IFS=

#刪除文件相匹配的圖案,即,不是與從陣列的字符結束X
rm -rf *[!"${x[*]}"]

+0

@eugene y:你寫了`IFS =`,但原來是'IFS =',你有錯字還是逗號?將IFS從行的其他內容中分離出來? – 2011-01-26 14:02:28

相關問題