為什麼更改目錄時通配符 * 不起作用?

為什麼更改目錄時通配符 * 不起作用?

例如我在我的目錄中:

/home/myname

然後我想將 CD 放入另一個目錄。

/home/pulsar/... 

由於我需要深入其他目錄,如何才能在不必輸入整行的情況下進行此操作?我試過

cd */thedirectoryiwanttogointo

但這行不通。我必須輸入整行。

答案1

您的通配符可能不起作用,因為:

  • 您提供的位置中沒有與通配符相符的內容,或者
  • 不只一場比賽。

在子目錄之間頻繁移動的常用方法(在 shell 中)是使用該CDPATH功能以及pushdpopd

CDPATH功能(可能首先出現在 tcsh 中)是一個以冒號分隔的目錄清單。如果您名字的父代thedirectoryiwanttogointo相當唯一,那麼您可以將父代添加到列表中。

為了進一步閱讀(你的 shell 的手冊頁應該放在第一位):

pushdpopd更新CDPATH,但仍可追溯到 20 世紀 90 年代中期。它們允許您在各自的命令期間保存當前目錄(“推入”堆疊)並恢復它(從堆疊“彈出”)cd。延伸閱讀:

其他人則使用 shell 別名或符號連結。這些在前往知名地點時最有用。

答案2

假設所有可能的目標目錄都在下面/home,並且目錄名稱中沒有換行符,您可以使用以下 shell 函數:

cds() {
    cd "$(find /home -type d -name "$1" | head -n 1)"
}

$ cds thedirectoryiwanttogointo

當然,根據子目錄和檔案的數量/home以及作業系統是否能夠在記憶體中快取所有樹的能力,效能會有很大差異。

在 GNU 系統上,您可以使用以下語法來加快速度並使其對於檔案名稱中的換行符號更可靠:

cds() {
    cd "$(find /home -type d -name "$1" -print -quit)"
}

一旦找到第一個匹配項,就會停止搜尋。

請注意,參數被視為一種模式,因此您可以執行以下操作:

cds 'foo*bar'

例如cd進入第一個目錄(未指定順序),其名稱以 . 開頭foo並以 . 結尾bar

答案3

您希望透過通配符擴充來尋找系統上任何位置的路徑。如果正確指定模式,您可以做到這一點:

cd /**/thedirectoryiwanttogointo

預設可以在 zsh 和 Fish 中工作,如果你首先在 Bash 中shopt -s globstar, 在tcsh 如果你set globstar,在ksh93如果你set -o globstar,在yash如果你set -o extended-glob

這是有效的,因為通配符在以 開頭的絕對路徑中使用,而/不是相對於當前目錄,並且當您選擇使用該**模式時,它會擴展到任意數量的子目錄。

雖然這會起作用,可能需要很長時間。您的 shell 必須在整個系統中搜尋匹配的檔案。您可以透過提供更長的前綴來減少更多的搜尋空間:

cd /home/pulsar/**/thedirectoryiwanttogointo/

鑽得越深,需要做的搜尋就越少。如果目錄樹相當稀疏,這不會花費太長時間並且實際上很實用。尾隨/確保擴充僅針對目錄,這消除了可能發生的各種歧義。

如果仍有多個匹配項,結果將取決於您的 shell。 Bash 和 Fish 將切換到按字母順序排列的第一個匹配,忽略歧義。 tcsh和yash會報錯。 zsh 和 ksh 會將其解釋為嘗試使用其高級目錄切換功能之一,並且大概報告錯誤。


如果您可能會重複使用同一目錄,請將父目錄放在進入CDPATH$FOO或者建立一個可以用來取代長路徑的shell 變數是更好的選擇。**如果您經常使用shell 變量,則可以將其與擴展結合以節省更多輸入。

答案4

如果您總是訪問同一個深層目錄,一個簡單的解決方案就是建立一個指向它的符號連結:

ln -s ~/foo/bar/baz/quux/etc/etc/etc/target ~/shortcut

如果您以前曾造訪過該目錄,另一個解決方案是在命令歷史記錄中搜尋您想要的名稱;按 ctrl-R 和要搜尋的字元。這是 bash 特有的,但我想大多數現代 shell 都有類似的功能。

相關內容