Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to efficiently transpose rows into columns in Vim?

Tags:

vim

perl

I have a data file like the following:

----------------------------
a b c d e .............
A B C D E .............
----------------------------

But I want it to be in the following format:

----------------------------
a A
b B
c C
d D
e E
...
...
----------------------------

What is the quickest way to do the transformation in Vim or Perl?

like image 595
stonebird Avatar asked Dec 12 '22 00:12

stonebird


2 Answers

Basically :.s/ /SpaceCtrl+vEnter/gEnterjma:.s/ /Ctrl+vEnter/gEnterCtrl+v'axgg$p'adG will do the trick. :)

OK, let's break that down:

  1. :.s/ /Ctrl+vEnter/gEnter: On the current line (.), substitute (s) spaces (/ /) with a space followed by a carriage return (SpaceCtrl+vEnter/), in all positions (g). The cursor should now be on the last letter's line (e in the example).
  2. j: Go one line down (to A B C D E).
  3. ma: Set mark a to the current position... because we want to refer to this position later.
  4. :.s/ /Ctrl+vEnter/gEnter: Do the same substitution as above, but without the Space. The cursor should now be on the last letter's line (E in the example).
  5. Ctrl+v'a: Select from the current cursor position (E) to mark a (that we set in step 3 above), using the block select.
  6. x: Cut the selection (into the " register).
  7. gg: Move the cursor to the first line.
  8. $: Move the cursor to the end of the line.
  9. p: Paste the previously cut text after the cursor position.
  10. 'a: Move the cursor to the a mark (set in step 3).
  11. dG: Delete everything (the empty lines left at the bottom) from the cursor position to the end of the file.

P.S. I was hoping to learn about a "built-in" solution, but until such time...

like image 67
Walter Avatar answered Dec 14 '22 12:12

Walter


Simple re-map of the columns:

use strict;
use warnings;

my @a = map [ split ], <>;  # split each line on whitespace and store in array
for (0 .. $#{$a[0]}) {      # for each such array element
    printf "%s %s\n", $a[0]->[$_], $a[1]->[$_];   # print elements in order
}

Usage:

perl script.pl input.txt
like image 26
TLP Avatar answered Dec 14 '22 12:12

TLP