sed & protobuf: 需要删除点

sed & protobuf: need to delete dots

我需要使用 sed 删除点,但不是所有点。

- repeated .CBroadcast_GetBroadcastChatUserNames_Response.PersonaName persona_names = 1
+ repeated CBroadcast_GetBroadcastChatUserNames_Response.PersonaName persona_names = 1

这里把repeated后面的点去掉,(repeated也可以是optional | required | extend)

- rpc NotifyBroadcastViewerState (.CBroadcast_BroadcastViewerState_Notification) returns (.NoResponse)
+ rpc NotifyBroadcastViewerState (CBroadcast_BroadcastViewerState_Notification) returns (NoResponse)

这里删除(

之后的点

它应该适用于具有不同内容的多个文件。


可以找到完整代码here

假设只有前导 . 需要删除,这里有一些 GNU sed 代码:

echo '.a_b.c c.d  (.e_f.g) ' | 
sed 's/^/& /;s/\([[:space:]{([]\+\)\.\([[:alpha:]][[:alpha:]_.]*\)//g;s/^ //'

输出:

a_b.c c.d  (e_f.g) 

除了 . 之外,它还检查两个字段,它们保持原样:

  1. 前导白space,或任何空位([,或{

  2. 尾随字母字符或 _..

不幸的是,虽然 \+ regexp 匹配一个或多个 spaces et al,它失败了如果 . 位于行首。 (将 \* 替换为 '*' 会匹配开头,但会错误地将 c.d 更改为 cd。)所以有一个问题...... s/^/& / 插入了一个虚拟对象space 在该行的开头,这样 \+ 就可以按预期工作,然后 s/^ // 删除虚拟 space。

一个可能更简单的解决方案(适用于 GNU sed 和 BSD/macOS sed):

sed -E 's/([[:space:][:punct:]])\.//g' file

如果 . 也可以作为行中的 第一个 字符出现,请使用以下变体:
sed -E 's/(^|[[:space:][:punct:]])\.//g' file

假设任何 . 前面有:

  • 一个空白字符(字符class[:space:]
    • 如: .
  • 或者一个标点符号(字符class[:punct:]
    • 如:(.

应该被删除,方法是只用 [=14= 之前的字符替换匹配的序列,通过正则表达式中的子表达式 (...) 捕获,并在替换字符串中引用 </code>(第一个捕获组)。</p> <hr> <p>如果你颠倒逻辑,你可以试试更简单的:</p> <pre><code>sed -E 's/([^[:alnum:]])\.//g' file

如果 . 也可以作为行中的 第一个 字符出现:
sed -E 's/(^|[^[:alnum:]])\.//g' file

这会替换所有 而非 (^) 前面有字母数字字符(字母或数字)的句点。