【发布时间】:2011-09-01 12:59:32
【问题描述】:
在 Bash 中,如果是 VAR="/home/me/mydir/file.c",我如何获得 "/home/me/mydir"?
【问题讨论】:
-
这里有更精巧复杂的真实目录路径解析stackoverflow.com/questions/29789204/…
标签: bash
在 Bash 中,如果是 VAR="/home/me/mydir/file.c",我如何获得 "/home/me/mydir"?
【问题讨论】:
标签: bash
【讨论】:
export 是不必要的,echos are useless.
export 是我的习惯,只是为了确保将变量传递给子shell。 echo 语句用于展示如何将输出转换为变量,但我可能应该全力以赴(我现在拥有)。尽管这些都不会真正影响答案的“肉”,但我会进行调整。对于改进我的答案的建设性批评,我总是很感激。
$ export VAR=/home/me/mydir/file.c
$ export DIR=${VAR%/*}
$ echo "${DIR}"
/home/me/mydir
$ echo "${VAR##*/}"
file.c
为了避免依赖basename 和dirname
【讨论】:
dirname 和 basename 有它们的位置,但如果路径已经在 shell 变量中,使用 shell 的内置工具比调用外部进程更高效和优雅。
在相关说明中,如果您只有文件名或相对路径,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
【讨论】:
readlink -m "$fname" 递归地规范化给定名称
如果您关心目标文件是符号链接,首先您可以检查它并获取原始文件。下面的 if 子句可能会对您有所帮助。
if [ -h $file ]
then
base=$(dirname $(readlink $file))
else
base=$(dirname $file)
fi
【讨论】:
HERE=$(cd $(dirname $BASH_SOURCE) && pwd)
new_path=$(dirname ${BASH_SOURCE[0]}) 获取完整路径的位置。您使用cd new_path 更改当前目录,然后运行pwd 以获取当前目录的完整路径。
【讨论】:
我正在玩这个并想出了一个替代方案。
$ 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
【讨论】:
您可以使用How to find the last field using 'cut' 的方法尝试这样的事情:
说明
rev 将 /home/user/mydir/file_name.c 反转为 c.eman_elif/ridym/resu/emoh/
cut 使用/ 作为分隔符,并选择第二个字段,即ridym/resu/emoh/,删除字符串直到/ 第一次出现
/home/user/mydir
$ VAR="/home/user/mydir/file_name.c"
$ echo $VAR | rev | cut -d"/" -f2- | rev
/home/user/mydir
【讨论】:
这是我用于递归修剪的脚本。当然,将 $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
【讨论】:
find 的输出上使用for 循环是一种反模式,也是许多错误的根源。这种构造本质上是有限的,如果find 产生的结果包含空格或其他shell 元字符,更不用说换行符了。