2011-05-25 307 views

回答

387

dirnamebasename是你要找的提取路徑組件的工具:

$ VAR=/home/me/mydir/file.c 

$ DIR=$(dirname "${VAR}") 

$ echo "${DIR}" 
/home/me/mydir 

$ basename "${VAR}" 
file.c 

他們不是內部猛砸命令,但他們是POSIX標準的一部分(見dirnamebasename ),因此絕大多數將運行Bash的系統都應該可用。

+0

爲什麼圍繞變量名使用括號而不是「$ VAR」? – user658182 2017-07-30 12:34:24

+0

https://stackoverflow.com/questions/8748831/when-do-we-need-curly-braces-around-shell-variables回答上述問題。 – user658182 2017-07-30 12:34:39

69
$ export VAR=/home/me/mydir/file.c 
$ export DIR=${VAR%/*} 
$ echo "${DIR}" 
/home/me/mydir 

$ echo "${VAR##*/}" 
file.c 

爲了避免依賴與basenamedirname

+1

因爲兩者都是POSIX的一部分,所以依賴不應該是一個問題。 – orkoden 2013-11-15 13:50:51

+0

orkoden,你說得對。我的答案的目的是表明沒有義務執行另外兩個過程。 bash是自足的用例。 – 2013-11-19 08:59:18

+2

我正在使用Emmanuel的方法,因爲我想傳遞文件或文件夾名稱,然後計算文件夾路徑。使用這個正則表達式是正確的,而當輸入文件夾時,dirname函數返回父文件夾。 – AnneTheAgile 2013-12-07 19:33:24

4

如果你關心的目標文件是符號鏈接,首先你可以檢查,並得到原始文件。下面的if子句可以幫助你。

if [ -h $file ] 
then 
base=$(dirname $(readlink $file)) 
else 
base=$(dirname $file) 
fi 
9

在相關說明中,如果只有文件名或相對路徑,dirname本身不會幫助。對我來說,答案最終爲readlink

fname='txtfile'  
echo $(dirname "$fname")    # output: . 
echo $(readlink -f "$fname")   # output: /home/me/work/txtfile 

然後,您可以將兩者結合起來得到目錄。

echo $(dirname $(readlink -f "$fname")) # output: /home/me/work 
+1

如果多於一個路徑組件不存在,則應使用'readlink -m「$ fname」'遞歸地規範給定的名稱 – EDkan 2016-09-20 12:13:09

2

我在玩這個,想出了一個替代方案。

$ VAR=/home/me/mydir/file.c 

$ DIR=`echo $VAR |xargs dirname` 

$ echo $DIR 
/home/me/mydir 

我喜歡的部分是很容易擴展備份樹:

$ DIR=`echo $VAR |xargs dirname |xargs dirname |xargs dirname` 

$ echo $DIR 
/home 
1

下面是我用遞歸微調的腳本。當然,用你想要的目錄替換$ 1。

BASEDIR="$1" 
IFS=$'\n' 
cd $BASEDIR 
for f in $(find . -type f -name ' *') 
do 
    DIR=$(dirname "$f") 
    DIR=${DIR:1} 
    cd $BASEDIR$DIR 
    rename 's/^ *//' * 
done