2012-04-04 28 views
4

我想转置一个非常长的文件,我担心它不会完全转置。转置列和行使用gawk

我的数据看起来是这样的:

Thisisalongstring12345678 1 AB abc 937 4.320194 
Thisisalongstring12345678 1 AB efg 549 0.767828 
Thisisalongstring12345678 1 AB hi 346 -4.903441 
Thisisalongstring12345678 1 AB jk 193 7.317946 

我希望我的数据是这样的:

Thisisalongstring12345678 Thisisalongstring12345678 Thisisalongstring12345678 Thisisalongstring12345678 
1       1       1       1 
AB      AB      AB      AB 
abc      efg      hi      jk 
937      549      346      193 
4.320194     0.767828     -4.903441     7.317946 

会第一个字符串的长度被证明是一个问题?我的文件比这大约2000行长很多。也有可能将第一个字符串的名称更改为Thisis234,然后转置?

+0

如果你愿意忍受每行20,000 * 25个字符(如此)的行(每行大约100 KiB左右),并且你使用的应用程序也是这样,那么'gawk '也可以。是的,你可以修剪长名字;设计算法并应用于输出或输入期间。 – 2012-04-04 00:50:24

回答

7

我不明白为什么它不会 - 除非你没有足够的内存。尝试下面的内容,看看你是否遇到问题。

输入:

$ cat inf.txt 
a b c d 
1 2 3 4 
. , + - 
A B C D 

awk程序:

$ cat mkt.sh 
awk ' 
{ 
    for(c = 1; c <= NF; c++) { 
    a[c, NR] = $c 
    } 
    if(max_nf < NF) { 
    max_nf = NF 
    } 
} 
END { 
    for(r = 1; r <= NR; r++) { 
    for(c = 1; c <= max_nf; c++) { 
     printf("%s ", a[r, c]) 
    } 
    print "" 
    } 
} 
' inf.txt 

运行:

$ ./mkt.sh 
a 1 . A 
b 2 , B 
c 3 + C 
d 4 - D 

现金

希望这会有所帮助。

+0

类似于[命令行枢纽](http://stackoverflow.com/questions/9475806/command-line-pivot) – ghoti 2012-04-04 00:38:53

+0

@ghoti同意,这是一个类似的主题,不同的方法 - 有利于OP有选择! – 2012-04-04 00:42:48

3

我试图icyrock.com的答案时,却发现我不得不改变:

for(r = 1; r <= NR; r++) { 
    for(c = 1; c <= max_nf; c++) { 

for(r = 1; r <= max_nf; r++) { 
    for(c = 1; c <= NR; c++) { 

得到NR列和max_nf行。所以icyrock的代码变成:

$ cat mkt.sh 
awk ' 
{ 
    for(c = 1; c <= NF; c++) { 
    a[c, NR] = $c 
    } 
    if(max_nf < NF) { 
    max_nf = NF 
    } 
} 
END { 
    for(r = 1; r <= max_nf; r++) { 
    for(c = 1; c <= NR; c++) { 
     printf("%s ", a[r, c]) 
    } 
    print "" 
    } 
} 
' inf.txt 

如果你不这样做,并使用非对称输入,如:

a b c d 
1 2 3 4 
. , + - 

你得到:

a 1 . 
b 2 , 
c 3 + 

即仍然3行4列(最后一个是空白的)。

0

对于@ ScubaFishi和@ icyrock代码:

“如果(max_nf < NF)” 似乎不必要。我删除了它,代码工作得很好。