sed 替换捕获组中的字符

sed 替换捕获组中的字符

我有这个,其中几乎做我想做的事

git show-branch --current $SHA1 \
  | sed --quiet --regexp-extended \
    's/^.*\* \[[a-z]+\/(B-[0-9]+)-([a-z0-9-]+)\].*/\1 \2/p' \
  | sed --quiet 2p

和输出

B-47120 java-11-take2

git show-branch正在输出这个

! [62cba3e2b3ba8e1115bceba0179fea6c569d9274] B-48141 remove env prefix
 * [ccushing/B-47120-java-11-take2] B-48141 remove env prefix
--
 * [ccushing/B-47120-java-11-take2] B-48141 remove env prefix
+* [62cba3e2b3ba8e1115bceba0179fea6c569d9274] B-48141 remove env prefix

我想要的输出是

B-47120 java 11 take2

它正在替换-第二个捕获组中的 's ,但我无法推理出替换-第二部分中的 only 的方法,因为我也必须捕获它。

我在适用于 Windows 的 git,并且仅限于附带的工具。尽管可能有更多的编程方法可以做到这一点(我可以使用 Perl)。如果可能的话我想看到sed答案。

更新

因为显然这并不明显。该模式本质上是username/ticketid-description(减去从 中获取该模式所需的内容git show-branch)。

  • 用户名应始终为 alpha
  • Ticketid 的格式始终为B-\d+
  • 描述(\2可以有任意数量的-应该转换为空格

我正在尝试以编程方式将其转换为prepare-commit-msg git钩子的 git 标题行。

答案1

尝试如下:

... |sed -nE '/^[[:blank:]*]+\[[^/]*\/(B-[0-9]+)-([^]]*)\].*/{
             s//\1 \2/; :a s/(B-[0-9]+ [^-]*)-(.*)/\1 \2/;ta; p; }'

尖端:

  • [^X]*: 匹配任何字符,但不匹配字符X(并且\newline 例外)。
  • [^X]*X: 匹配任何字符,但不匹配后跟字符 的字符X(也包括ewline 例外) 。\nX
  • (...)\1:捕获第一个、\2第二个等反向引用的组匹配(您只能进行最多\9反向引用)。
  • :label s/find/replace/; t label:跳转到label成功替换并重复命令。

或者更短一些(取决于输入格式):

... |sed -nE '/^[^/]*\/([^]]*)\].*/{
             s//\1/; :a s/(B-[0-9]+)(.*)-([^-]*)$/\1\2 \3/;ta; p; }'

答案2

我提出以下建议,假设下面提到的一些事情(告诉这些假设是否错误):

# select the line with the slash character '/'
# replace the first '-' for other char not possible to be in the string, example '@'
# replace all '-' for spaces
# replace '@' for '-'
# capture everything between the '/' an the ']', remove everything else
$ sed -n -e '\:/:{s:-:@:;s:-: :g;s:@:-:;s:^.*/\([^]]*\).*:\1:p;q}'
B-47120 java 11 take2

\:/:选择包含斜杠的行/

* [ccushing/B-47120-java-11-take2] B-48141 remove env prefix

s:-:@:替代,非贪婪,-所以@只有第一个。

* [ccushing/B@47120-java-11-take2] B-48141 remove env prefix

s:-: :g代替-空白,贪婪。

* [ccushing/B@47120 java 11 take2] B 48141 remove env prefix

s:@:-:替代@-

* [ccushing/B-47120 java 11 take2] B 48141 remove env prefix

s:^.*/\([^]]*\).*:\1:p;q捕获/和之间的内容],删除其他所有内容,打印并退出。

B-47120 java 11 take2

答案3

使用 GNU sed 的构造,您可以获得如图所示的输出。

注意:我没有更改您的正则表达式,只是调整了一些部分。如果假设您需要第四场比赛,则将其更改{2}为。{4}

sed  --quiet --regexp-extended '
  s/^.*\* \[[a-z]+\/(B-[0-9]+)-([a-z0-9-]+)\].*/\1 \2/;T;G
  s/\n{2}$//;Ta
  s/-/ /2gp;q
  :a;z;H
' file

相关内容