使用sed从行中删除“ *”?

时间:2018-08-03 08:54:42

标签: regex bash shell sed

我想获取每一行的第一个字段,但是碰巧其中一个将是'*',我希望跳过它。

git branch -vv

返回

  master 34a8e20 [origin/master: behind 14] renamed yml's
* ss_doc 3ebc755 [origin/ss_doc: gone] PRD configuration
  ss_fix d0f4a4c [origin/ss_fix: gone] Merge branch 'ss_fix' into 'master'
  ss_v   c3b4635 [origin/ss_v: gone] remove composes

当我应用以下sed命令时,结果如下:

git branch -vv |  sed -r  's|\*?(\w+).+|\1|'

结果是

  master
* ss_doc
  ss_fix
  ss_v

我不明白为什么它会在匹配组中捕获“ *”。我尝试了其他解决方法,但这是最接近目标的方法。怎么不接“ *”?

2 个答案:

答案 0 :(得分:2)

请注意,sed替换命令仅替换匹配的内容。不匹配的内容将不被替换。

您的模式尝试匹配*,但是如果在当前位置找不到*,则它尝试匹配(\w+).+模式(因为\*?匹配一个或星号)。由于不匹配,sed替换命令会将不匹配的*保留在结果中。

您需要确保星号匹配。由于*和单词char之间存在空格,因此可以将其与\s*[[:space:]]*匹配:

sed -r 's|\*?\s*(\w+).+|\1|'

另一种方法是在字符char之前匹配任何空格和*

sed -r 's|[*[:space:]]*([[:alnum:]_]+).*|\1|'
          ^^^^^^^^^^^^^

或者,将PCRE模式与grep配合使用以仅匹配您需要的内容:

grep -oP '^\W*\K\w+'

或者,删除开头的所有非单词字符,然后awk删除第一个字段:

sed 's/^[^[:alnum:]_]*//' | awk '{print $1}'

请参见online demo

答案 1 :(得分:1)

只需告诉awk在前导空格和星号之后打印第一个字段:

$ awk -F'[ *]+' '{print $2}' file
master
ss_doc
ss_fix
ss_v

在任何UNIX系统上的任何shell中使用任何awk都可以使用。如果您喜欢sed,则可以与任何sed一起使用:

$ sed 's/^[ *]*\([^ ]*\).*/\1/' file
master
ss_doc
ss_fix
ss_v