Search and replace control characters (^@, ^M, ^I....) in vi

Somehow, the space characters are represented by ^@ in vi.

It's not vi that did that. Although you type command lines in shells with spaces between the arguments, command lines are actually discrete sequences of strings internally, not one long space-separated string. The shell separated the command line into individual argument strings before the command was launched.

In C, strings are terminated with NUL characters and those are shown as ^@.

How can one replace special characters particularly those that start with carat symbol?

In order to type those characters, you must prefix them with Control-v for literal next character.

For example in this case: Control-v followed by Control-@.

The special character that introduces literal next characters is normally Control-v but it is actually configurable. Type stty -a to find out what it is set to. Look for lnext in the output.


That symbol represents a NULL character, with ASCII value 000.

You could try:

:%s/\%x00/ /g

Alternative:

On a keyboard where the @ symbol is on top of the 2 key (thanks Celada) you can do:

  • %s/<CTRL-2>/ /g (on PC)

  • %s/<CTRL-SHIFT-2>/ /g (on Mac)

where <CTRL-2> means first press down the CTRL on PC, keeping it as pressed down, hit 2, release CTRL.

and <CTRL-SHIFT-2> means first press down the control on Mac, keeping it as pressed down, press down shift on Mac, keeping it as pressed down, hit 2, release control and shift.

Finally, both of the two commands should result in %s/^@/ /g on screen. ^@ means a single character, not ^ followed by @, so you can't just type ^ and @ in a row in the above command.

This command replaces all the ^@ with space characters.

(Source)