Environment-Variables

如何從 shell 變數中獲取路徑的文件名部分

  • September 24, 2018

shell 變數保存路徑。如何獲得其文件名部分?

在 bash(1) 中,我進行了實驗,發現使用."${i/*\///}"wherei環境變數的名稱可以做到這一點。這種方法不僅醜陋,而且在路徑不包含任何/字元的情況下也是錯誤的。

我將展示一個需要這種功能的實際案例。假設我們要為源目錄中的每個 PDF 文件創建一個指向目前目錄的符號連結。

$ for i in /source/path/*.pdf; do\
 ln -s "$i" ."${i/*\///}"; \
 done

${i##*/}

這適用於 Posix shell,包括bash, dash, ksh,等。來自Posix Shell & Utilities 規範zsh的標準POSIX 參數擴展部分:

${參數##$$ word $$}

刪除最大前綴模式。這個詞應該被擴展以產生一個模式。然後參數擴展將產生參數,其中與模式匹配的前綴的最大部分被刪除。

或者,傳統上,該basename命令已用於此目的。 **警告:**性能可能成為一個重要問題,因為basename它是作為外部命令(例如/usr/bin/basename)實現的。因為您是在循環中執行此操作,所以您將為每個文件呼叫一個外部命令。在 1000 個文件的列表中,這可能是 0.05 秒(參數擴展)和 2.0 秒(basename命令)之間的差異。但是對於 10,000 個文件的列表,它可能是 0.5 秒(擴展)與 20 秒 ( ) 之間的差異basename。隨著文件數量的增加,性能差異變得更加極端。

為了可讀性和性能,您可以實現自己的basename功能,例如:

mybasename() { echo "${1##*/}"; }

(為函式選擇更好的名稱,和/或完整basename命令行界面的實現,留給讀者作為練習。:)

引用自:https://unix.stackexchange.com/questions/470986