在Bash中获取文件路径参数中的最后一个目录名/文件名
在Bash中获取文件路径参数中的最后一个目录名/文件名
我正在尝试为托管在我们开发服务器上的SVN编写一个post-commit钩子。我的目标是尝试自动将提交的项目副本检出到服务器上托管的目录中。然而,为了能够检出到我们项目托管的同一子目录,我需要能够只读取传递给脚本的目录字符串中的最后一个目录。\n例如,如果我对项目“example”进行SVN提交,我的脚本会将\"/usr/local/svn/repos/example\"作为第一个参数接收。我需要从字符串的末尾获取\"example\",然后与另一个字符串连接起来,这样我就可以检出到\"/server/root/example\",并立即查看变更。
在Bash中,可以通过调用外部的basename
来获取路径的最后一部分。然而,我们也可以使用Bash的参数展开功能来实现这一目的,而无需调用外部命令。具体的方法如下:
dir="/path/to/whatever/" dir="${dir%/}" # 去除末尾的斜杠(如果有的话) subdir="${dir##*/}"
这段代码使用了Bash的参数展开功能,删除了字符串中最后一个斜杠之前的部分,从而得到了路径的最后一部分。
在我的Mac电脑上,使用这种子字符串表示法比起使用dirname/basename要快上一个数量级,尤其是当你需要对数千个文件中的每一个进行简单操作的情况下。
非常感谢分享这个方法。对于那些开始怀疑为什么它不起作用,或者我是不是唯一一个傻瓜的未来读者们,希望这个解答能帮到你们。上面的解答假设$1
包含了要取出最后一部分的路径。这一部分我之前忽略了。我的用例是: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
原因:此问题的出现是因为在Bash中,使用basename和dirname命令来获取文件路径的最后一个目录名和文件名时,如果文件路径中含有空格,会导致命令执行错误,无法得到正确的结果。
解决方法:为了解决文件路径中含有空格的问题,可以使用引号将命令中的文件路径部分包裹起来,以确保命令的正确执行。具体的解决方法如下所示:
some_path="a/b/c" echo $(basename "$some_path") echo $(basename "$(dirname "$some_path")") echo $(basename "$(dirname "$(dirname "$some_path")")")
输出结果:
c b a
这样可以确保即使文件路径中含有空格,命令也能正确地获取到文件路径的最后一个目录名和文件名。