dir=/home/smith/Desktop/Test
parentdir="$(dirname "$dir")"
如果有斜线也可以工作。
显然,父目录是通过简单地附加点文件名给出的:
/home/smith/Desktop/Test/.. # unresolved path
但是您必须想要解析的路径(没有任何点点路径组件的绝对路径):
/home/smith/Desktop # resolved path
使用 dirname
的最佳答案的问题在于,当您输入带点的路径时,它们不起作用:
$ dir=~/Library/../Desktop/../..
$ parentdir="$(dirname "$dir")"
$ echo $parentdir
/Users/username/Library/../Desktop/.. # not fully resolved
这更强大:
dir=/home/smith/Desktop/Test
parentdir=$(builtin cd $dir; pwd)
您可以提供它 /home/smith/Desktop/Test/..
,也可以提供更复杂的路径,例如:
$ dir=~/Library/../Desktop/../..
$ parentdir=$(builtin cd $dir; pwd)
$ echo $parentdir
/Users # the fully resolved path!
注意:使用 builtin
确保不会调用 cd
的用户定义函数变体,而是调用没有输出的默认实用程序形式。
eval
不是很好。您可以使用 pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/null
代替 eval
吗?
eval
:只需执行 parentdir=$(cd -- "$dir" && pwd)
。由于 cd
在子 shell 中运行,因此您不需要 cd
回到我们原来的位置。 --
在这里是为了防止 $dir
的扩展以连字符开头。 &&
只是为了防止 cd
没有成功时 parentdir
有非空内容。
dir=$(builtin cd "../../.."; pwd)
,因为路径名中有空格,其他一切都失败了。该应用程序是由 Platypus 构建的伪应用程序,其中隐藏了实际脚本。谢谢
只需在要查找其父目录的目录中工作时使用 echo $(cd ../ && pwd)
。该链还具有没有尾部斜杠的额外好处。
echo
。
...但是“看到的 here”被破坏了。这是修复:
> pwd
/home/me
> x='Om Namah Shivaya'
> mkdir "$x" && cd "$x"
/home/me/Om Namah Shivaya
> parentdir="$(dirname "$(pwd)")"
> echo $parentdir
/home/me
另一个答案的动机
我喜欢非常简短、清晰、有保证的代码。如果它不运行外部程序,则加分点,因为您需要处理大量条目的那一天,它会明显更快。
原则
不确定您拥有和想要什么保证,所以无论如何都要提供。
如果你有保证,你可以用非常短的代码来做到这一点。这个想法是使用 bash 文本替换功能来剪切最后一个斜杠以及后面的任何内容。
回答原始问题的简单到更复杂的情况。
如果路径保证结束时没有任何斜线(进出)
P=/home/smith/Desktop/Test ; echo "${P%/*}"
/home/smith/Desktop
如果路径保证以一个斜线结尾(进出)
P=/home/smith/Desktop/Test/ ; echo "${P%/*/}/"
/home/smith/Desktop/
如果输入路径可能以零或一个斜杠(而不是更多)结尾,并且您希望输出路径以不带斜杠的方式结束
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/
do
P_ENDNOSLASH="${P%/}" ; echo "${P_ENDNOSLASH%/*}"
done
/home/smith/Desktop
/home/smith/Desktop
如果输入路径可能有许多多余的斜杠,并且您希望输出路径结束时没有斜杠
for P in \
/home/smith/Desktop/Test \
/home/smith/Desktop/Test/ \
/home/smith///Desktop////Test//
do
P_NODUPSLASH="${P//\/*(\/)/\/}"
P_ENDNOSLASH="${P_NODUPSLASH%%/}"
echo "${P_ENDNOSLASH%/*}";
done
/home/smith/Desktop
/home/smith/Desktop
/home/smith/Desktop
${BASH_SOURCE[0]}
使用参数扩展,输入是否有尾部斜杠,如果它不是通过 source
或 .
获取的,这将是脚本的完整路径。
如果 /home/smith/Desktop/Test/../
是您想要的:
dirname 'path/to/child/dir'
如 here 所示。
bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'")
。链接代码也是错误的。
Test
所在的目录运行 dirname Test
。
如果您只需要父目录的名称:
parent_dir_name=$(basename $(dirname $PWD))
根据您是否需要绝对路径,您可能需要采取额外的步骤:
child='/home/smith/Desktop/Test/'
parent=$(dirname "$child")
abs_parent=$(realpath "$parent")
使用这个:export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")"
如果你想要第四个父目录
export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")"
如果您想要第三个父目录
export MYVAR="$(dirname "$(dirname $PWD)")"
如果您想要第二个父目录
丑陋但高效
function Parentdir()
{
local lookFor_ parent_ switch_ i_
lookFor_="$1"
#if it is not a file, we need the grand parent
[ -f "$lookFor_" ] || switch_="/.."
#length of search string
i_="${#lookFor_}"
#remove string one by one until it make sens for the system
while [ "$i_" -ge 0 ] && [ ! -d "${lookFor_:0:$i_}" ];
do
let i_--
done
#get real path
parent_="$(realpath "${lookFor_:0:$i_}$switch_")"
#done
echo "
lookFor_: $1
{lookFor_:0:$i_}: ${lookFor_:0:$i_}
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_})
parent_: $parent_
"
}
lookFor_: /home/Om Namah Shivaya
{lookFor_:0:6}: /home/
realpath {lookFor_:0:6}: /home
parent_: /home
lookFor_: /var/log
{lookFor_:0:8}: /var/log
realpath {lookFor_:0:8}: /UNIONFS/var/log
parent_: /UNIONFS/var
lookFor_: /var/log/
{lookFor_:0:9}: /var/log/
realpath {lookFor_:0:9}: /UNIONFS/var/log
parent_: /UNIONFS/var
lookFor_: /tmp//res.log/..
{lookFor_:0:6}: /tmp//
realpath {lookFor_:0:6}: /tmp
parent_: /
lookFor_: /media/sdc8/../sdc8/Debian_Master//a
{lookFor_:0:35}: /media/sdc8/../sdc8/Debian_Master//
realpath {lookFor_:0:35}: /media/sdc8/Debian_Master
parent_: /media/sdc8
lookFor_: /media/sdc8//Debian_Master/../Debian_Master/a
{lookFor_:0:44}: /media/sdc8//Debian_Master/../Debian_Master/
realpath {lookFor_:0:44}: /media/sdc8/Debian_Master
parent_: /media/sdc8
lookFor_: /media/sdc8/Debian_Master/../Debian_Master/For_Debian
{lookFor_:0:53}: /media/sdc8/Debian_Master/../Debian_Master/For_Debian
realpath {lookFor_:0:53}: /media/sdc8/Debian_Master/For_Debian
parent_: /media/sdc8/Debian_Master
lookFor_: /tmp/../res.log
{lookFor_:0:8}: /tmp/../
realpath {lookFor_:0:8}: /
parent_: /
始于想法/评论 Charles Duffy - 2014 年 12 月 17 日 5:32,主题为 Get current directory name (without full path) in a Bash script
#!/bin/bash
#INFO : https://stackoverflow.com/questions/1371261/get-current-directory-name-without-full-path-in-a-bash-script
# comment : by Charles Duffy - Dec 17 '14 at 5:32
# at the beginning :
declare -a dirName[]
function getDirNames(){
dirNr="$( IFS=/ read -r -a dirs <<<"${dirTree}"; printf '%s\n' "$((${#dirs[@]} - 1))" )"
for(( cnt=0 ; cnt < ${dirNr} ; cnt++))
do
dirName[$cnt]="$( IFS=/ read -r -a dirs <<<"$PWD"; printf '%s\n' "${dirs[${#dirs[@]} - $(( $cnt+1))]}" )"
#information – feedback
echo "$cnt : ${dirName[$cnt]}"
done
}
dirTree=$PWD;
getDirNames;
如果出于某种原因您有兴趣向上导航特定数量的目录,您也可以这样做:nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd)
。这将提供 3 个父目录
这将上升到父文件夹
cd ../
不定期副业成功案例分享
parentdir=$(dirname `pwd`)