I was trying to replace the pipe character with a comma in a file using vi. I tried using
:%s/\|/,/g
to replace all pipes with commas in the following string.
|a|b|c|d
But this didn’t work and resulted in a comma before each letter as follows.
,|,a,|,b,|,c,|,d
Searching on the internet, I found a suggestion that worked.
:%s/\v\|/,/g
this correctly replaced the pipes to commas as expected.
a,b,c,d
After some digging through the vi manual, I found out that this was because vi has a special meaning for ‘\|’ when used in patterns.
In a vi substitution pattern, some characters are taken literally and gain special meaning if preceded by a backslash. At the same time, there are some other characters that have a special meaning by default and need to be preceded by a backslash for a literal match.
This is governed by the ‘magic’ option in vi.
The pipe character is non-magic by default which means it need not be escaped for a literal search. So the expression
:%s/|/,/g
would have also worked in this case.
The expression
:%s/\|/,/g
escaped the pipe character and therefore made it “magic”. Pipe, in its special form is treated as a separator. So in this case, the expression reads
“Find nothing and replace with a comma i.e., add a comma before every character.”
Using \v makes every following character to be treated as special or magical. Therefore
:%s/\v|/,/g
makes the pipe character from non-magical to magical.
But escaping pipe with a slash makes it non-magical again.
:%s/\v\|/,/g
The expression, therefore, now reads as
“Replace pipe character with comma”
which works as intended.
[...] commas in |a|b|c|d But this didn’t work and resulted in the following…. [full post] rahulj51 Miles to code uncategorized 0 0 0 0 0 [...]