我想这会给我 git 中当前分支的名称。
echo "${`git symbolic-ref HEAD`##refs/heads}"
然而,这会导致
-bash: ${`git symbolic-ref HEAD`##refs/heads}: bad substitution
是否可以在单行命令结果上使用 ## 而不将结果存储在中间变量中,或者我是否必须使用其他方法,例如sed
?
答案1
不可以bash
,但你可以zsh
:
printf '%s\n' "${$(git symbolic-ref HEAD)#refs/heads}"
会在那里工作。
或者你总是可以用以下方法进行剥离sed
:
printf '%s\n' "$(git symbolic-ref HEAD | sed '1s|^refs/heads||')"
如果要删除的部分包含换行符,情况会变得更加复杂。例如,如果要剥离的部分是$'1\n2\n3\n'
,您需要类似以下内容:
cmd1 -- "$(cmd2 | sed '1{$!N;$!N;$!N; s/^1\n2\n3\n//;}')"
因此,您不妨使用一个临时变量,它也有保留cmd2
退出状态的好处:
strip=$'1\n2\n3\n'
out=$(cmd2); cmd2_status=$?
cmd1 -- "${out#"$strip"}"
答案2
不,恐怕这是不可能的,因为这个##
习语属于多变的仅扩展,因此您始终必须引用现有变量。
但是,对于您的情况,您可能会喜欢以下技巧:
sh -c 'echo "${*##refs/heads}"' - "`git symbolic-ref HEAD`"
或者: (作为更好的巴什主义)
sh -c 'echo "${*##refs/heads}"' -- "$(git symbolic-ref HEAD)"
这将运行一个非交互式的命令sh
,并将命令的输出git
作为其参数,然后在该参数上使用##
惯用语。
如果您可以相信命令的输出已被充分清理(即不包含*
或其他通配符),您可以省去自己键入双引号。