I've copy pasted some data from a webpage:
x y
0 9
2 22.6
4 44.2
5 62.1
7 96.9
8 113.4
10 133.4
11 137.6
15 148.4
17 149.3
I'd like to transpose and slightly transform the data such:
x = 0,2,4,...
y = 9, 22.6, 44.2...
I know how to put commas after each column using v mode but I don't know how that could work for when I have double digits or a column with mixed length of characters.
I'm more concerned about how to transpose, if that is the command that I want?
How can I get my data into the desired form:
x = 0,2,4,...
y = 9, 22.6, 44.2...
If you have the external tool rs
installed see second approach below,
otherwise:
My approach would centre around using visual block mode with Ctrl
+
v
and applying the J
command, and cleaning up with a substitution. First
select the second column in visual block and delete it, then paste it below the
x column:
x
0
2
4
5
7
8
10
11
15
17
y
9
22.6
44.2
62.1
96.9
113.4
133.4
137.6
148.4
149.3
Then you can do vipJ
, on each block, to select that data and put it on one
line (FYI: vipJ
is going to v
isual mode, selecting i
nside p
aragraph,
and then J
oining those lines):
x 0 2 4 5 7 8 10 11 15 17
y 9 22.6 44.2 62.1 96.9 113.4 133.4 137.6 148.4 149.3
A quick substitution :s/\s\+/, /g
can replace spaces with commas:
, x, 0, 2, 4, 5, 7, 8, 10, 11, 15, 17,
, y, 9, 22.6, 44.2, 62.1, 96.9, 113.4, 133.4, 137.6, 148.4, 149.3
Then you can just clean up the extra commas, and add the =
sign, remove the
blank line etc:
x = 0, 2, 4, 5, 7, 8, 10, 11, 15, 17
y = 9, 22.6, 44.2, 62.1, 96.9, 113.4, 133.4, 137.6, 148.4, 149.3
If there are many columns, you probably don't want to repeat the procedure above for each one... in that case you can probably record the above as a macro in a repeatable way or check out the approach below.
The rs
tool allows you to reshape a data array, so you could filter your file
(or a visual selection, or passing a range) through the tool from inside vim
like so:
:%!rs -T -C,
The flags -T
means to transpose, and -C
specifies the column delimiter in
the output (a comma in our case) to produce:
x,0,2,4,5,7,8,10,11,15,17,
y,9,22.6,44.2,62.1,96.9,113.4,133.4,137.6,148.4,149.3,
Then as in the pure vim approach, you just need to do some clean up:
:%s/,/, /g
produces:
x, 0, 2, 4, 5, 7, 8, 10, 11, 15, 17,
y, 9, 22.6, 44.2, 62.1, 96.9, 113.4, 133.4, 137.6, 148.4, 149.3,
Then you can just clean up the extra commas and add the =
sign:
x = 0, 2, 4, 5, 7, 8, 10, 11, 15, 17
y = 9, 22.6, 44.2, 62.1, 96.9, 113.4, 133.4, 137.6, 148.4, 149.3
If needed, you could run the external command (also on a visual selection, or
passing a range) :%!column -t
to align things nicely:
x = 0, 2, 4, 5, 7, 8, 10, 11, 15, 17
y = 9, 22.6, 44.2, 62.1, 96.9, 113.4, 133.4, 137.6, 148.4, 149.3