
我想建立一個自訂的內建函數bash
——例如time
。這可能嗎?如果不是的話,可以在另一個shell嗎?
例如,我想這樣做:map find -name '*.js' | xargs grep func1
並讓它find -name '*.js' | xargs grep func1
在 CWD 中的每個目錄中運行。請注意,一切包括管道被傳遞到map
.
目標是跨多個目錄應用指令。我寫了一個名為which的腳本,map
它涵蓋eval
了$1
所有ls
產生的內容。但是,如果我要運行的命令包括管道、重定向等,那麼我必須引用字串內的所有內容。我正在尋找一種不必這樣做的方法。
另外,我只是很好奇這是否可能;)
答案1
ATT ksh、bash 和 zsh 都有一個動態模組載入系統,允許將附加程式碼載入到現有的 shell 實例中,並且動態載入的程式碼可以實現新的內建函數。不過,您所要求的不僅僅是一個新的內建函數:它需要新的語法,而且我認為沒有一個 shell 可以處理這個問題。您必須修改 shell 原始碼中的解析器。
在 zsh 中,您可以接近您想要的語法:
for x (*/) (cd $x && pipeline)
您可以建立別名alias map='for x (*/) (cd $x &&'
,但末尾仍需要右括號。你可以透過粗暴的 hack 獲得你想要的語法:
alias map='map__PWD=$PWD; for x (./*/ "") cd $map__PWD${x#.}/ && [[ -z $x ]] || '
這是如此醜陋、脆弱和不可概括的,我不打算解釋它。如果您不完全了解它的工作原理,請不要考慮使用它。
答案2
在這種情況下,類似
find . -type f -name "*.js" -exec grep -qF "func1" {} \; -print
可能足以找到*.js
目前目錄中或目前目錄下包含字串的檔案的名稱func1
。
如果您想避免目前目錄中的檔案:
find . -mindepth 2 -type f -name "*.js" -exec grep -qF "func1" {} \; -print
使用-mindepth 2
,find
不會符合「深度 1」(即目前目錄中)的任何內容。
最後一件事基本上滿足了您的要求。它有效地grep
在目前目錄的每個子目錄中運作。