【问题标题】:How to multiply every other columns in multiple files如何将多个文件中的每隔一列相乘
【发布时间】:2018-05-01 23:27:37
【问题描述】:

全部

我有三个这样的文件:file1 file2 file3,它们的行数和列数相同。每个文件包含 72 列(前两列相同,第 (2n+1) 列也相同),like

文件1

20170101 1 1 1 2 2 3 3...  
20170101 2 1 2 2 4 3 4...
20170101 3 1 5 2 3 3 6 ...

文件2

20170101 1 1 0 2 1 3 3...  
20170101 2 1 2 2 4 3 2...
20170101 3 1 3 2 4 3 1 ..

文件3

20170101 1 1 2 2 3 3 0...  
20170101 2 1 1 2 4 3 2...
20170101 3 1 4 2 4 3 0 ..

从第 4 列开始,我想每隔一列相乘,例如 col4,col6 ,col8,col10... 输出应该是

20170101 1 1 0 2 6 3 0...  
20170101 2 1 4 2 64 3 16...
20170101 3 1 60 2 48 3 0 ..

我试过了,但是从 col4 开始的所有列都会相乘。

paste file1 file2 file3| awk '{ for(i=3;i<=NF/2; i++) printf("%4.2E ", $i*$(i+NF/2)*$(i+NF))); printf("\n"); }'

感谢您的帮助。

【问题讨论】:

  • 给新手的建议:如果一个答案解决了您的问题,请点击旁边的大复选标记 (✓) 接受它,也可以选择投票(投票至少需要 15 声望)点)。如果您发现其他答案有帮助,请给他们投票。接受和投票有助于未来的读者。请看【相关帮助中心文章】[1] [1]:stackoverflow.com/help/someone-answers

标签: awk


【解决方案1】:

假设所有输入文件的行数相同:

$ awk '{getline a < "f2"; getline b < "f3"; split(a,s1); split(b,s2)}
       {for(i=4;i<=NF;i+=2) $i*=s1[i]*s2[i]; print}' f1
20170101 1 1 0 2 6 3 0
20170101 2 1 4 2 64 3 16
20170101 3 1 60 2 48 3 0
  • getline a &lt; "f2" 从 file2 中获取一行,保存在变量 a
  • split(a,s1)a中的内容拆分(与默认输入行拆分相同)并保存在变量s1
  • for(i=4;i&lt;=NF;i+=2) $i*=s1[i]*s2[i]需要操作
  • print 打印修改后的输入行 - 如果需要,使用格式化
  • 有关 getline 警告,请参阅 AllAboutGetline

【讨论】:

  • 您的解决方案比我的 +1 好得多! ;-)
【解决方案2】:

由于您使用的是paste 命令,我将在我的回答中使用它,否则我真的建议您使用 Sundeep 的解决方案和getline

以下粘贴命令将交错 3 个文件:

$ paste -d '\n' file1 file2 file3
20170101 1 1 1 2 2 3 3 
20170101 1 1 0 2 1 3 3  
20170101 1 1 2 2 3 3 0
20170101 2 1 2 2 4 3 4
20170101 2 1 2 2 4 3 2
20170101 2 1 1 2 4 3 2
20170101 3 1 5 2 3 3 6
20170101 3 1 3 2 4 3 1
20170101 3 1 4 2 4 3 0

你可以在输出上使用awk这个输出来生成你需要的输出:

$ paste -d '\n' file1 file2 file3 | awk '{for(i=4;i<=NF;i+=2)if(NR>1){a[i]*=$i;}else{a[i]=$i}if(NR%3==0){printf $1 OFS $2 OFS; for(i in a){printf $(i-1) OFS a[i] OFS;a[i]=1}printf ORS;}}'
20170101 1 1 0 2 6 3 0 
20170101 2 1 4 2 64 3 16 
20170101 3 1 60 2 48 3 0 

说明:

{
    for(i=4;i<=NF;i+=2) #loop on all other columns 
        if(NR>1){a[i]*=$i;} #make the product computation for all lines greater than 1
        else{a[i]=$i} #initialize the array on the first line
    if(NR%3==0){ #every 3 lines 
        printf $1 OFS $2 OFS; #print the first 3 fields
        for(i in a){ #then loop on the array and print cell and computed product
            printf $(i-1) OFS a[i] OFS;
            a[i]=1} #reset all elements of the array to 1
        printf ORS;} #print EOL
}

【讨论】:

    猜你喜欢
    • 2013-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多