【问题标题】:Get last dirname/filename in a file path argument in Bash在 Bash 的文件路径参数中获取最后一个目录名/文件名
【发布时间】:2011-03-18 16:02:55
【问题描述】:

我正在尝试为 SVN 编写一个提交后挂钩,它托管在我们的开发服务器上。我的目标是尝试自动将已提交项目的副本签出到服务器上托管的目录。但是,我需要能够仅读取传递给脚本的目录字符串中的最后一个目录,以便签出到托管我们项目的同一子目录。

例如,如果我对项目“example”进行 SVN 提交,我的脚本将“/usr/local/svn/repos/example”作为其第一个参数。我需要从字符串末尾获取“example”,然后将其与另一个字符串连接,这样我就可以签出到“/server/root/example”并立即查看更改。

【问题讨论】:

    标签: linux bash shell svn


    【解决方案1】:

    不使用外部命令打印文件名,

    运行:

    fileNameWithFullPath="${fileNameWithFullPath%/}";
    echo "${fileNameWithFullPath##*/}" # print the file name
    

    此命令的运行速度必须比 basenamedirname 快。

    【讨论】:

      【解决方案2】:

      以下方法可用于获取路径名的任意路径:

      some_path=a/b/c
      echo $(basename $some_path)
      echo $(basename $(dirname $some_path))
      echo $(basename $(dirname $(dirname $some_path)))
      

      输出:

      c
      b
      a
      

      【讨论】:

      • 不适用于有空格的路径......你可以用引号克服它......它以某种方式工作echo "$(basename "$(dirname "$pathname")")"
      【解决方案3】:

      Bash 无需调用外部basename 即可获取路径的最后一部分:

      subdir="/path/to/whatever/${1##*/}"
      

      【讨论】:

      • 在我的 Mac 上,使用子字符串表示法比 dirname / basename 快一个数量级以上,因为您对几千个文件中的每一个都做一些微不足道的事情。
      • d=/home/me/somefolder;subdir="/$d/${1##*/}" 我最终得到了类似//home/me/somefolder// 的东西,$d 实际上来自循环for d in $(find $SOMEFOLDER -maxdepth 1 -type d); 使用subdir=$(basename $d) 按预期工作。
      • @ButtleButkus:您应该使用while 而不是for 来迭代find 的输出(find -print0 | xargs -0 更好)或使用通配符:for d in $SOMEFOLDER/*/(最后的斜线有效)比如-type d——如果你shopt -s globstar,你可以在Bash 4中使用**进行递归,但是可能会出现“参数列表太长”的消息)。请注意,命令的${1} 部分表示脚本或函数的第一个参数。您可能需要使用${d##*/} 或其他一些变量或参数规范,或者确保在$1 中传递参数
      • @DennisWilliamson 非常感谢 分享对于任何开始怀疑为什么它不起作用或者我是这里唯一的愚蠢的未来读者?。以上答案假设$1 包含the path from which last component is to be taken out。我错过了那部分。我的用例:target_path='/home/user/dir1/dir2/dir3/'; target_path="${target_path%/}"; last_component=${target_path##*/}; echo $last_component - 有效?
      • 查看此处了解如何为什么${1##*/}工作:unix.stackexchange.com/a/171786/15070
      【解决方案4】:

      basename 确实删除了路径的目录前缀:

      $ basename /usr/local/svn/repos/example
      example
      $ echo "/server/root/$(basename /usr/local/svn/repos/example)"
      /server/root/example
      

      【讨论】:

      • basename 绝对是我正在寻找的。但是,如何将参数的基本名称存储到变量中?例如。 SUBDIR="/path/to/whatever/$(basename $1)"
      • @tj111: 听起来好像不是$1,或者$1 是空的
      • 不幸的是,如果你包装命令,basename 不是一个好主意。只是要记住的事情
      猜你喜欢
      • 2014-04-21
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 2011-12-26
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 2014-07-09
      相关资源
      最近更新 更多