如何将列随后除以所有其他列或除以所有其他列的倍数?

时间:2016-11-23 11:03:48

标签: bash unix awk

任何人都可以帮我解决以下问题:
我有一个制表符分隔文件,每行中的列数不同。我需要将第一列中的值随后除以所有其他列中的值。因此,我想将最终的数字转换为新文件。

example_file.txt

0.0002  0.2    0.2    0.6   
0.03    0.3    0.7     
0.004   0.1    0.2    0.005   0.3  0.005  

我用1填充所有空行,以避免除以0的问题:

awk '{for(i=NF+1;i<=6;i++)$i="1"}1' < example_file.txt > example_file_filled.txt

example_file_filled.txt

0.002   0.2   0.2      0.6    1   1    
0.03    0.3   0.7        1    1   1    
0.004   0.1   0.2    0.005    0.3 0.005    

预期产出:

output.txt

0.083  
0.14  
26666.66  

我知道我可以:
- 将第一列除以第二列,然后取此值并除以第三列等 - 或将所有列从第二列乘以最后一列,并使用此值除以第一列

我试图使用的第一种可能性:

awk '{$1=$1/$2; $2=""; print $0 }' example_file_filled.txt 

这将第一行除以第二行并打印输出结果,后跟尚未用于除法的数字。我试图循环它以完成它,直到没有第二行,但我没有管理。

有人可以提出解决方案吗?我的真实文件有> 100列。我主要使用bash / unix,但我也很乐意从其他方法中学习 提前谢谢!

2 个答案:

答案 0 :(得分:1)

使用循环遍历其他列,然后除以:

awk '{ val = 1; for (i = 2; i <= NF; ++i) val *= $i; print $1 / val }' file

或者只是进行连续的划分,再次使用循环:

awk '{ for (i = 2; i <= NF; ++i) $1 /= $i; print $1 }' file

由您决定如何处理任何列中0的存在 - 如果您愿意,可以在执行除法之前添加if

答案 1 :(得分:0)

使用perl

$ cat ip.txt 
0.002  0.2    0.2    0.6   
0.03    0.3    0.7     
0.004   0.1    0.2    0.005   0.3  0.005  

$ perl -lane '$a=$F[0]; $a /= $_ foreach (@F[1..$#F]); print $a' ip.txt 
0.0833333333333333
0.142857142857143
26666.6666666667

限制小数点:

$ perl -lane '$a=$F[0]; $a /= $_ foreach (@F[1..$#F]); printf "%.3f\n", $a' ip.txt 
0.083
0.143
26666.667


有关perl命令行选项

的说明,请参阅Perl flags -pe, -pi, -p, -w, -d, -i, -t?