我需要一个命令,该命令将返回bash中指定路径的顶级基本目录。
我有一种可行的方法,但是看起来很丑:
echo "/go/src/github.myco.com/viper-ace/psn-router" | cut -d "/" -f 2 | xargs printf "/%s"
似乎有更好的方法,但是我见过的所有替代方法似乎都更糟。
谢谢您的建议!
答案 0 :(得分:2)
作为一种本机重击方法,它不产生任何子shell,也不会调用其他程序(因此,编写这些程序是为了最大程度地减少开销),这种方法在带有转行符的 目录的特殊情况下可以正常工作:
topdir() {
local re='^(/+[^/]+)'
[[ $1 =~ $re ]] && printf '%s\n' "${BASH_REMATCH[1]}"
}
与这里的大多数其他解决方案一样,调用将类似于outvar=$(topdir "$path")
。
为进一步减少开销,您可以传入目标变量名而不是捕获stdout:
topdir() {
local re='^(/+[^/]+)'
[[ $1 =~ $re ]] && printf -v "$2" '%s' "${BASH_REMATCH[1]}"
}
...用作:topdir "$path" outvar
,然后"$outvar"
将扩展为结果。
答案 1 :(得分:0)
一个选项正在使用awk
:
echo "/go/src/github.myco.com/viper-ace/psn-router" |
awk -F/ '{print FS $2}'
/go
答案 2 :(得分:0)
这是一种可能性。仍然很丑。处理诸如////////home/path/to/dir
之类的东西。仍然在换行符上爆炸。
$ echo "////home/path/to/dir" | sed 's!/*\([^/]*\).*!\1!g'
/home
换行符:
$ cd 'testing '$'\n''this'
$ pwd
/home/path/testing
this
$ pwd | sed 's!/*\([^/]*\).*!/\1!g'
/home
/this
如果您知道您的目录将被更一般地命名,那么您和anubhava的解决方案肯定看起来更具可读性。
答案 3 :(得分:0)
不确定更好,但使用sed
$ echo "/go/src/github.myco.com/viper-ace/psn-router" | sed -E 's_(/[^/]+).*_\1_'
/go
答案 4 :(得分:0)
这是函数中的bash,sed和tr:
#!/bin/bash
function topdir(){
dir=$( echo "$1" | tr '\n' '_' )
echo "$dir" | sed -e 's#^\(/[^/]*\)\(.*\)$#\1#g'
}
topdir '/go/src/github.com/somedude/someapp'
topdir '/home/somedude'
topdir '/with spaces/more here/app.js'
topdir '/with newline'$'\n''before/somedir/somefile.txt'
致谢!