Wednesday, December 16, 2009

Re: Rectify some bad csv

I agree with Christian -- you seem to keep changing the problem
definition which makes it awfully hard to provide a solution; and
given that you've changed the definition several times, each time
to get a solution to the problem from each of us, please try to
respect our time by giving an accurate and thorough description
of the problem

> It is more complicated, the script should complete empty fields
> between semi colonn only if all previous field of the current line
> are identical to the same position fields of the previous line.
>
> DDD_TTTT/CTRL/PT/VERSION;_INSTALL;CSTRING;;;;;;;;;;;
> DDD_TTTT/CTRL/PT/VERSION;;;ANYTHINGELSE
>
> should be
>
> DDD_TTTT/CTRL/PT/VERSION;_INSTALL;CSTRING;;;;;;;;;;;
> DDD_TTTT/CTRL/PT/VERSION;_INSTALL;CSTRING;ANYTHINGELSE

Gaaaaa, your in-line commenting made those hard to understand.
I've stripped out the cruft. You'll see that your textual
description and your before/after doesn't actually match. Using
the textual description, you'd get

DDD_TTTT/CTRL/PT/VERSION;_INSTALL;;ANYTHINGELSE

because "all the previous field of the current line" only match
those of the previous line up through the "/VERSION;" portion,
not the _INSTALL portion. You'd have to run the :g command a
second time to bring the CSTRING down (because it only matches up
to the CSTRING after you've pulled down the _INSTALL).

You can tweak my :g command to the following one-liner:

2,$g/;/let p=split(getline(line('.')-1), ';', 1) | let
c=split(getline('.'), ';', 1) | s/.*/\=join(map(range(len(c)),
'(!strlen(c[v:val]) && (c[:(v:val-1)]==p[:(v:val-1)])) ?
(p[v:val]) : (c[v:val])'), ';')

which does what your textual description requests, but you'd have
to run it multiple times (if you have N columns, you could
conceivably have to execute the :g command N-1 times, though this
isn't too hard using something like

5@:

to re-execute the command-line 5 times).

You could also tweak it so that you only check that the 1st
columns match which would be done something like

2,$g/;/let p=split(getline(line('.')-1), ';', 1) | let
c=split(getline('.'), ';', 1) | s/.*/\=join(map(range(len(c)),
'(!strlen(c[v:val]) && (c[0]==p[0])) ? (p[v:val]) : (c[v:val])'),
';')

-tim


--
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php

No comments: