Search code examples
sedvim

Add space between double forward slash followed immediately with a character in Vim


I am trying to update the comments in a file starting with a double forward slash and no space; it immediately starts with text. This is what the file looks like:

//comment1
//comment2

I want to change it to:

// comment1
// comment2

Comments can start anywhere in the line and may be preceded by code, which I don't want to change.

For that, I tried the pattern (find two // followed immediately by characters from the range a-z or A-Z and then insert space: sed -i 's/\/\/[a-zA-Z]/\/\/ [a-zA-Z]/g' file

But the result was:

// [a-zA-Z]omment1

instead of inserting a space.


Solution

  • Your command worked not as you intended because in case of replacement [a-zA-Z] is just a string.

    To use something found by regex you need to use capturing group. Basically, when you enclose something in your regex in parentheses you tell regex "remember this for later".

    So your regex should be //([a-zA-Z]), and symbol that immediately followed slashes will be "remembered", and could be referenced as \1 in replacement.

    One caveat about groups and sed: by default GNU sed uses BRE, and all symbols with special meaning should be preceded with \ to gain this special meaning. Other wise . is just a dot.

    To not push excessive \'s into expression you could use switch -E, that tells sed to use ERE. In this case . is any symbol, and \. just a dot.
    (Difference between ERE and BRE is much wider, but it's out of the scope this question)

    Also, sed accepts any symbol immediately following s as separator, so ease reading your command you can use : instead of /. And as @phd correctly pointed out in this case you don't have to escape /, that increases readability even more.

    So, the final command could be:

    sed -Ei 's://([a-zA-Z]):// \1:g' file
    

    Caution: sed is not aware of context of your code. if sed will encounter // inside string declaration, it will be replaced as well.