在Bash中的最后两个斜杠之间提取一个字符串

时间:2015-10-27 23:03:26

标签: bash

我知道这可以像我在https://stackoverflow.com/a/33379831/3962126上回答的那样使用正则表达式轻松完成,但我需要在bash中执行此操作。

所以我发现Stackoverflow上最接近的问题就是这个问题bash: extracting last two dirs for a pathname,但区别在于如果

DIRNAME = /a/b/c/d/e

然后我需要提取

d

6 个答案:

答案 0 :(得分:5)

这可能相对较长,但执行速度比大多数前面的答案要快得多(除了zsh-only和ja之外),因为它只使用内置于bash中的字符串操作而不使用子shell扩展:< / p>

string='/a/b/c/d/e'  # initial data
dir=${string%/*}     # trim everything past the last /
dir=${dir##*/}       # ...then remove everything before the last / remaining
printf '%s\n' "$dir" # demonstrate output
上面使用了

printf,因为echo对所有值都不能可靠地工作(考虑它在/a/b/c/-n/e的GNU系统上会做什么)。

答案 1 :(得分:4)

这是一个纯粹的bash解决方案:

[[ $DIRNAME =~ /([^/]+)/[^/]*$ ]] && printf '%s\n' "${BASH_REMATCH[1]}"

与其他一些答案相比:

  • 它匹配最后两个斜杠之间的字符串。因此,例如,如果d它不匹配DIRNAME=d/e
  • 它更短更快(只使用内置函数并且不会创建子进程)。
  • 支持最后两个斜杠之间的任何字符(有关详情,请参阅Charles Duffy&#39; s answer)。

另请注意,这不是在bash中分配变量的方式:

DIRNAME = /a/b/c/d/e
       ^ ^

这些空格是错误的,所以删除它们:

DIRNAME=/a/b/c/d/e

答案 2 :(得分:1)

OMG,也许这很明显,但最初并不适合我。我得到了正确的结果:

dir=$(basename -- "$(dirname -- "$str")")
echo "$dir"

答案 3 :(得分:1)

使用awk

echo "/a/b/c/d/e" | awk -F / '{ print $(NF-1) }' # d

编辑:当路径包含换行符时,这不起作用,并且当少于两个斜杠时仍然提供输出,请参阅下面的注释。

答案 4 :(得分:0)

使用sed

如果你想获得第四个元素

DIRNAME="/a/b/c/d/e"
echo "$DIRNAME" | sed -r 's_^(/[^/]*){3}/([^/]*)/.*$_\2_g'

如果你想获得前一个元素

DIRNAME="/a/b/c/d/e"
echo "$DIRNAME" | sed -r 's_^.*/([^/]*)/[^/]*$_\1_g'

答案 5 :(得分:-1)

使用zsh参数替换也很酷

echo ${${DIRNAME%/*}##*/}

我认为它比双$()更快,因为它不需要任何子流程。

基本上它首先从右侧切掉,然后将剩下的所有左侧切掉。