2011-05-25 256 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