Substitute individual characters within matching delimiters in vim

62 views Asked by At

I have a csv file where some cells contain , between "...". I need to change only the commas between the quotation marks to semicolons without the rest of the commas on the line getting replaced. That is, I have something like this:

x,"y,z",a

And only the comma between y and z should be replaced with ;. How should this be done in vim?

3

There are 3 answers

1
builder-7000 On BEST ANSWER

For a single pair of quotes per line you could use:

%s/\v("[^"]*)@<=,(.*")@=/;/g

Input:

x,"y,z,a",b

output:

x,"y;z;a",b

For more than a pair of quotes per line you could use the following awk command:

:!awk -F'"' -v OFS='"' '{ for (i=2; i<=NF; i+=2) gsub(",", ";", $i) } 1' infile > outfile

This command is based on a question in Unix StackExchange. It will set a quote " as the field separator and substitute commas in every other field using gsub.

1
Kent On

This vim command :s with substitute() function call will do the job easily:

%s/"\zs[^"]*/\=substitute(submatch(0),',',';','g')

For example:

enter image description here

0
rgt47 On

If there is only one comma between the double quotes, and no more than one match per line the following substitute command should work:

:%s/\(".*\),\(.*"\)/\1;\2/