1

I need to delete dots using sed, but not all dots.

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

Here the dot after repeated, (repeated also can beoptional | required | extend) should be deleted

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

And here delete dot after (

It should work on multiple files with different content.


Full code can be found here

4

2 回答 2

3

A perhaps simpler solution (works with both GNU sed and BSD/macOS sed):

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

In case a . can also appear as the first character on a line, use the following varation:
sed -E 's/(^|[[:space:][:punct:]])\./\1/g' file

The assumption is that any . preceded by:

  • a whitespace character (character class [:space:])
    • as in:  .
  • or a punctuation character (character class [:punct:])
    • as in: (.

should be removed, by replacing the matched sequence with just the character preceding the ., captured via subexpression (...) in the regular expression, and referenced in the replacement string with \1 (the first capture group).


If you invert the logic, you can try the simpler:

sed -E 's/([^[:alnum:]])\./\1/g' file

In case a . can also appear as the first character on a line:
sed -E 's/(^|[^[:alnum:]])\./\1/g' file

This replaces all periods that are not (^) preceded by an alphanumeric character (a letter or digit).

于 2017-07-04T17:58:12.270 回答
1

Assuming only the leading . needs removal, here's some GNU sed code:

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

Output:

a_b.c c.d  (e_f.g) 

Besides the ., it checks for two fields, which are left intact:

  1. Leading whitespace, or any opening (, [, or {.

  2. Trailing alphabetical chars or also _ or ..

Unfortunately, while the \+ regexp matches one or more spaces et al, it fails if the . is at the beginning of the line. (Replacing the \* with a '*' would match the beginning, but would incorrectly change c.d to cd.) So there's a kludge... s/^/& / inserts a dummy space at the beginning of the line, that way the \+ works as desired, then a s/^ // removes the dummy space.

于 2017-07-04T17:24:27.567 回答