Linuxコンソール上で、Excelのように行と列を入れ替えたい時がある。
そんなときは、以下のようにawkなどを使うことで実現可能だ。

1.awkを使う

まずはawkを使う場合。
以下のようにすることで、行と列の入れ替えが可能だ。

awk '
{ for (i=1; i<=NF; i++)  { a[NR,i] = $i } } NF>p { p = NF }
END {
    for(j=1; j<=p; j++) { str=a[1,j]; for(i=2; i<=NR; i++){ str=str" "a[i,j]; }
        print str
    }
}' 対象ファイルPATH
[root@BS-PUB-CENT7-01 ~]# cat /tmp/test1_1.txt
id      name    prefecture      value
1       aaa     1       123
2       bbb     2       544
3       ccc     1       65745
4       ddd     1       122
5       eee     2       222
6       fff     1       444
7       ggg     3       566
8       hhh     4       111
9       iii     3       12
10      bbb     2       1243
11      ddd     1       4423
[root@BS-PUB-CENT7-01 ~]# awk '
> { for (i=1; i<=NF; i++)  { a[NR,i] = $i } } > NF>p { p = NF }
> END {
>     for(j=1; j<=p; j++) { str=a[1,j]; for(i=2; i<=NR; i++){ str=str" "a[i,j]; } >         print str
>     }
> }' /tmp/test1_1.txt
id 1 2 3 4 5 6 7 8 9 10 11
name aaa bbb ccc ddd eee fff ggg hhh iii bbb ddd
prefecture 1 2 1 1 2 1 3 4 3 2 1
value 123 544 65745 122 222 444 566 111 12 1243 4423

2.perlを使う

perlのワンライナーで入れ替えを行うこともできる。

cat ファイルPATH | perl -anF'\t|\n' -e'$n=@F-1if!$n;for(0..$n){push@{$$m[$_]},$F[$_]}''END{print map{join"\t",@$_,"\n"}@$m}'
[root@BS-PUB-CENT7-01 ~]# cat /tmp/test1_1.txt | perl -anF'\t|\n' -e'$n=@F-1if!$n;for(0..$n){push@{$$m[$_]},$F[$_]}''END{print map{join"\t",@$_,"\n"}@$m}'
id      1       2       3       4       5       6       7       8       9       10      11
name    aaa     bbb     ccc     ddd     eee     fff     ggg     hhh     iii     bbb     ddd
prefecture      1       2       1       1       2       1       3       4       3       2      1
value   123     544     65745   122     222     444     566     111     12      1243    4423

3.pythonを使う

pythonのワンライナーでも、行と列の入れ替えが行える。

cat ファイルPATH | python -c "import sys; print('\n'.join(' '.join(c) for c in zip(*(l.split() for l in sys.stdin.readlines() if l.strip()))))"
[root@BS-PUB-CENT7-01 ~]# cat /tmp/test1_1.txt | python -c "import sys; print('\n'.join(' '.join(c) for c in zip(*(l.split() for l in sys.stdin.readlines() if l.strip()))))"
id 1 2 3 4 5 6 7 8 9 10 11
name aaa bbb ccc ddd eee fff ggg hhh iii bbb ddd
prefecture 1 2 1 1 2 1 3 4 3 2 1
value 123 544 65745 122 222 444 566 111 12 1243 4423

4.rubyを使う

rubyのワンライナーでも、表の行列入れ替えを行える。

cat /tmp/test1_1.txt | ruby -e'puts readlines.map(&:split).transpose.map{|x|x*" "}'
[root@BS-PUB-CENT7-01 src]# cat /tmp/test1_1.txt | ruby -e'puts readlines.map(&:split).transpose.map{|x|x*" "}'
id 1 2 3 4 5 6 7 8 9 10 11
name aaa bbb ccc ddd eee fff ggg hhh iii bbb ddd
prefecture 1 2 1 1 2 1 3 4 3 2 1
value 123 544 65745 122 222 444 566 111 12 1243 4423

5.datamashコマンドを使う

以前紹介したdatamashコマンドを使うことで、表の行列入れ替えが簡単に行える。
なお、区切り文字がデフォルトではタブになってる点は注意が必要。

datamash transpose < ファイルPATH
[root@BS-PUB-CENT7-01 ~]# cat /tmp/test1_1.txt | datamash transpose
id      1       2       3       4       5       6       7       8       9       10      11
name    aaa     bbb     ccc     ddd     eee     fff     ggg     hhh     iii     bbb     ddd
prefecture      1       2       1       1       2       1       3       4       3       2      1
value   123     544     65745   122     222     444     566     111     12      1243    4423

6.transposeコマンドを使う

transposeというコマンドを使うことでも、表の行列入れ替えを行える。
まず以下のコマンドでまずインストールをする。

wget http://downloads.sourceforge.net/project/transpose/transpose/transpose-2.0/2.0/transpose-2.0.zip
unzip transpose-2.0.zip
cd transpose-2.0/src
gcc transpose.c -o /usr/bin/transpose

で、行列の反転は以下。

transpose -t ファイルPATH
[root@BS-PUB-CENT7-01 src]# transpose -t /tmp/test1_1.txt
id      1       2       3       4       5       6       7       8       9       10      11
name    aaa     bbb     ccc     ddd     eee     fff     ggg     hhh     iii     bbb     ddd
prefecture      1       2       1       1       2       1       3       4       3       2      1
value   123     544     65745   122     222     444     566     111     12      1243    4423

7.rsコマンドを使う(2016/07/05 追記)

BSD系のコマンドであるrsコマンドで「-T」オプションを使うことで、行列変換が可能だ。
Ubuntuならば、以下のコマンドでインストールできる(Macでは最初から使える)。

sudo apt-get install rs

pasteのようにも使えるので、だいぶ便利だ。

blacknon@BS-PUB-UBUNTU-01:/tmp$ seq 50 | rs 0 10
1   2   3   4   5   6   7   8   9   10
11  12  13  14  15  16  17  18  19  20
21  22  23  24  25  26  27  28  29  30
31  32  33  34  35  36  37  38  39  40
41  42  43  44  45  46  47  48  49  50
blacknon@BS-PUB-UBUNTU-01:/tmp$ seq 50 | rs 0 10 | rs -T
1   11  21  31  41
2   12  22  32  42
3   13  23  33  43
4   14  24  34  44
5   15  25  35  45
6   16  26  36  46
7   17  27  37  47
8   18  28  38  48
9   19  29  39  49
10  20  30  40  50

いくつか方法はあるので、環境や状況に合わせて使い分けていきたい。