Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find every third value and insert cr or newline in VIM

Tags:

python

vim

So I have several large datasets that I need to make more readable and currently I'm having to go in and move to each 3rd value and insert a newline. I've tried several things in VIM to get this to work, but none seem to return the value that I'm looking for. Here's some of my data:

(0.96260310749184663, 4.3830008206495812, 0.84922658632317849),
(0.96260310749184663, 5.0000002088986637, 1.049701855818201),
(0.96260310749184697, 5.6169993576359696, 0.8492264385213405),
(0.96260310749184719, 5.9983257940402384, 0.32437568665165911),
(0.96260310749184719, 5.9983258053918069, -0.32437572732698844),
(0.96260310749184719, 5.6169994358349786, -0.84922691097323821),
(0.96260310749184697, 5.0000000093711492, -1.0497019267383632)

What I need to do is make it look like this instead:

(0.96260310749184663, 4.3830008206495812, 
 0.84922658632317849),
(0.96260310749184663, 5.0000002088986637, 
 1.049701855818201),
(0.96260310749184697, 5.6169993576359696, 
 0.8492264385213405),
(0.96260310749184719, 5.9983257940402384, 
 0.32437568665165911),
(0.96260310749184719, 5.9983258053918069, 
 -0.32437572732698844),
(0.96260310749184719, 5.6169994358349786, 
 -0.84922691097323821),
(0.96260310749184697, 5.0000000093711492, 
 -1.0497019267383632)

I used this on a selection to try and get it to move that 3rd value down, but it duplicated the entire thing and then moved the entire line down:

:'<,'>s/\([-[0-9.]\+,\s[-[0-9.]\+,\)/\1\r&/g

I also tried removing the 1 to make it work, but that didn't work either. So is there any way I can capture that 3rd value and insert a carriage return or newline to make this work? Thanks.

Edit---

I apologize for mis-communicating part of my problem: The data at the top is all on one line, not several lines. It looks like this:

(0.31852533878680489, 0.10352149350126813, -0.0046069731261429991), (0.31852526554320226, -0.103521543762028, -0.0046069731261429991), (0.19682845687859715, -0.27102285045297636, -0.004606973126142444), (-8.1184530326649769e-05, -0.33500267513407755, -0.0046069731261416669), (-0.19699089317458821, -0.27102292369657782, -0.0046069731261408897), (-0.31868770183919259, -0.10352150714022559, -0.0046069731261403346), (-0.31868770183919221, 0.10352156674487166, -0.0046069731261403346), 
like image 435
John P Avatar asked Dec 07 '22 18:12

John P


2 Answers

:g/./norm! 2Wi^M

Explanation:

  • :g/./{cmd} will run the {cmd} on every line
  • norm! will execute the following string as normal mode commands
  • 2Wi^M Move 2 WORDS then insert a return
  • ^M is accomplished by pressing <c-v><cr> or <c-q><cr>.

It is very tempting to do %norm! 2Wi^M, but this will fail as it messes up the lines that are being worked on.

like image 62
Peter Rincker Avatar answered Dec 28 '22 23:12

Peter Rincker


Two approaches

1. ex commands and formatting

My first thought was textwidth:

:se tw=50
:g/./norm! gqq
:%s/^[^(]/ &/g

This

  1. sets text width to 50 chars
  2. reformats each (nonempty) line
  3. inserts a space at the start of any lines which don't start with (

2. use a macro

Alternatively: make a macro

gg
qq2f,a<CR><Esc>j0q
100000@q

Rationale:

  1. go to begin of buffer
  2. record macro q (qq starts recording, q ends recording)
    • 2f, - forward to second comma
    • a<CR><Esc> - append newline
    • j0 - next line, move caret to first character
  3. rinse and repeat (100000 is the number of times to repeat; processing will stop when the macro fails (e.g. at end of file)
like image 37
sehe Avatar answered Dec 28 '22 23:12

sehe