Radhamohan Parashar
Radhamohan Parashar

Reputation: 175

search and Replace in specific pattern using VIM

Input : -

{NSM_QOS_DEFAULT_COS_OVERRIDE_NOT_CONFIGURED,  "%% nsm_qos_default_cos_override_not_configured"},
{NSM_QOS_COS_SETTING_FAILED,      "%% nsm_qos_cos_setting_failed"},
{NSM_QOS_ACCESS_GROUP_ALREADY_ATTACHED_TO_CLASS_MAP,    "%% nsm_qos_access_group_already_attached_to_class_map"},

Output should be : -

  {NSM_QOS_DEFAULT_COS_OVERRIDE_NOT_CONFIGURED,  "%% nsm qos default cos override not configured"},
{NSM_QOS_COS_SETTING_FAILED,      "%% nsm qos cos setting failed"},
{NSM_QOS_ACCESS_GROUP_ALREADY_ATTACHED_TO_CLASS_MAP,    "%% nsm qos access group already attached to class map"},

I tried a search pattern :-

%s/\l_\l/\l \l/g

but output is not proper , it's replacing(character also which i don't want) like this :

before : - nsm_qos
after : - nm os     (but i need like this -->  nsm qos )

Upvotes: 1

Views: 68

Answers (2)

Tom Lord
Tom Lord

Reputation: 28285

Your problem is that in the command:

:%s/\l_\l/\l \l/g

you are not actually storing the value of the letters on either side of _, so you're losing them as part of the search+replace.

In fact, when replacing values in vim, \l has a special meaning: "Make the first letter of the following word lower-case" - which is clearly not what you intended!

There are a few ways this can be solved. The simplest is to store both letters in capture groups, and use these values in the replace section (\1 and \2 respectively):

:%s/\(\l\)_\(\l\)/\1 \2/g

A slightly simpler way of writing this is to use vim's very magic modifier: \v - which eliminates the need for most of those ugly back-slashes:

:%s/\v(\l)_(\l)/\1 \2/g

Or, an alternative approach is to use vim's lookbehind/lookahead functionality. For example, you can use \zs and \ze to mark the start/end of the matched string respectively, and do the following:

:%s/\l\zs_\ze\l/ /g

In this case, the letters on either side of _ are no longer included in the search - and therefore do not get replaced. (So, we do not need to store them in a variable.)

Upvotes: 1

Kent
Kent

Reputation: 195029

I guess this should work for you:

%s/\v([a-z])_([a-z])/\1 \2/g  
"Note, this requires the `ignorecase` option not set.

or

%s/\v(\l)_(\l)/\1 \2/g

Upvotes: 1

Related Questions