在Bash脚本中获取当前目录名(没有完整路径)

在Bash脚本中获取当前目录名(没有完整路径),bash,shell,Bash,Shell,如何在bash脚本中只获取当前工作目录名,或者更好地,只获取终端命令 pwd提供当前工作目录的完整路径,例如/opt/local/bin,但我只想bin使用该程序。对于您的情况: % basename "$PWD" bin 您可以使用pwd和basename的组合。例如 #!/bin/bash CURRENT=`pwd` BASENAME=`basename "$CURRENT"` echo "$BASENAME" exit; 不需要basename,尤其不需要运行pwd的子shell

如何在bash脚本中只获取当前工作目录名,或者更好地,只获取终端命令

pwd
提供当前工作目录的完整路径,例如
/opt/local/bin
,但我只想
bin
使用该程序。对于您的情况:

% basename "$PWD"
bin

您可以使用pwd和basename的组合。例如

#!/bin/bash

CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`

echo "$BASENAME"

exit;

不需要basename,尤其不需要运行pwd的子shell(which);shell可以在内部使用以下方法完成此操作:

result=${PWD###*/}分配给变量
要打印到标准输出的printf'%s\n'${PWD###*/}
#…对于不寻常的名称,比echo更可靠
#(考虑名为-e或-n的目录)
printf'%q\n'${PWD###*/}要打印到标准输出,引用以用作shell输入
#…用于使隐藏字符可读。

请注意,如果在其他情况下应用此技术(不是
PWD
,而是保存目录名的其他变量),则可能需要修剪任何后面的斜杠。下面使用bash来处理多个尾部斜杠:

dirname=/path/to/somewhere//
shopt -s extglob           # enable +(...) glob syntax
result=${dirname%%+(/)}    # trim however many trailing slashes exist
result=${result##*/}       # remove everything before the last / that still remains
printf '%s\n' "$result"
或者,如果没有
extglob

dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}"                  # remove everything before the last /
$echo“${PWD###*/}”

​​​​​

以下命令将导致在bash脚本中打印当前工作目录

pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR

这条线太棒了!这里还有一种味道:

pwd | awk -F / '{print $NF}'

我喜欢选择的答案(Charles Duffy),但是如果您在一个符号链接目录中,并且想要目标目录的名称,请小心。不幸的是,我不认为它可以在一个单参数展开表达式中完成,也许我错了。这应该起作用:

target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
为了了解这一点,我们做了一个实验:

cd foo
ln -s . bar
echo ${PWD##*/}
报告“酒吧”

肮脏的 要显示路径的前导目录(不产生/usr/bin/dirname的fork exec):

这将例如转换foo/bar/baz->foo/bar

echo "$PWD" | sed 's!.*/!!'

如果您使用的是Bourne shell或
${PWD###*/}
则不可用。

您可以使用basename实用程序从字符串中删除以/结尾的任何前缀和后缀(如果字符串中存在),并打印 标准输出的结果

$basename <path-of-directory>
$basename

只需使用:

pwd | xargs basename

格雷普怎么样:

pwd | grep -o '[^/]*$'

令人惊讶的是,没有人提到这个仅使用内置bash命令的替代方案:

i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
作为一种额外的奖励,您可以通过以下方式轻松获得父目录的名称:

[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"

这些将在bash4.3-alpha或更新版本上运行。

我通常在sh脚本中使用它

SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder

你可以用它来自动化事情

下面grep和regex也在工作

>pwd | grep -o "\w*-*$"

对于那些像我这样的骑师:

find $PWD -maxdepth 0 -printf "%f\n"
我非常喜欢使用,这是GNU coreutils的一部分。

使用:

basename "$PWD"

IFS=/ 
var=($PWD)
echo ${var[-1]} 
将内部文件名分隔符(IFS)转回空格

IFS= 

IFS后面有一个空格。

如果您只想在bash提示符区域中查看当前目录,可以在
~
中编辑
.bashrc
文件。将行中的
\w
更改为
\w

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
运行
source~/.bashrc
,它将只在提示区域显示目录名


参考:

有很多方法我特别喜欢,因为它避免了一个新的过程,但在知道这一点之前,我用awk解决了它

pwd | awk -F/ '{print $NF}'

请不要这样做。反勾号创建了一个子shell(因此是一个fork操作)——在本例中,您将使用它们两次![作为一种附加的,尽管是风格上的诡辩——变量名应该是小写的,除非您要将它们导出到环境中,或者它们是特殊的保留大小写]。作为第二种风格,诡辩背景应该替换为$()。仍然是fork,但可读性更强,所需的扩展更少。按照惯例,环境变量(PATH、EDITOR、SHELL等)和内部SHELL变量(BASH_VERSION、RANDOM等)完全大写。所有其他变量名称应为小写。由于变量名区分大小写,此约定可避免意外重写环境变量和内部变量。具体取决于约定。有人可能会说,所有的shell变量都是环境变量(取决于shell),因此所有shell变量都应该包含在所有的caps中。其他人可能会根据作用域进行争论——全局变量都是大写,而局部变量是小写,这些都是全局变量。还有人可能会认为,将变量全部大写会增加一层额外的对比,而shell脚本中的命令也都是小写的简短但有意义的单词。我可能同意,也可能不同意,但我已经看到了这三种观点的运用${PWD###*/}和$PWD之间的区别是什么?@Mr#u Chimp前者是一个参数扩展操作,它修剪目录的其余部分以仅提供basename。我的答案中有一个链接,指向有关参数扩展的文档;如果您有任何问题,请随时关注。@stefgosselin
$PWD
是内置bash变量的名称;所有内置变量名都包含在所有大写字母中(以区别于局部变量,局部变量应至少包含一个小写字符)
result=${PWD#*/}
的计算结果不是
/full/path/to/directory
;相反,它只剥离第一个元素,使其成为
path/to/directory
;使用两个
#
字符使模式匹配贪婪,尽可能多地匹配字符。阅读答案中链接的参数扩展页面了解更多信息。请注意,
pwd
的输出并不总是与
$pwd
的值相同,这是由于通过符号链接进行
cd
操作、bash是否设置了
-o physical
选项等引起的复杂性。在处理自动挂载目录时,这会变得特别糟糕,在自动挂载目录中记录物理路径而不是逻辑
IFS=/ 
var=($PWD)
echo ${var[-1]} 
IFS= 
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
pwd | awk -F/ '{print $NF}'