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
いくつか方法はあるので、環境や状況に合わせて使い分けていきたい。
