如何用另一列值减去一列值?

时间:2018-03-09 09:20:57

标签: perl awk

我有两个带有一列值的文件,如下面的附件。我想用file1中的所有值减去file2的第一个值,这些减法填充输出文件中的第一列,然后填充file2的第二个值,其中包含file1中的所有值...

输出如下:

 -4(2-6)    -5    0    1
  0(2-2)    -1    4    5
 -2(2-4)    -3    2    3
 -3(2-5)    -4    1    2
 -6(2-8)    -7   -2   -1

第一列括号中的表达式仅供说明使用,需要在输出中丢弃。

此外,列中的值数可能会有所不同。

非常感谢!

file1        file2

   6           2          
   2           1          
   4           6          
   5           7          
   8                      

1 个答案:

答案 0 :(得分:2)

如果我理解正确,那么

awk 'NR == FNR { src[FNR] = $1; next } { for(i = 1; i <= length(src); ++i) { printf("%d\t", src[i] - $1); } print ""; }' file2 file1

产生所需的输出。其工作原理如下:

NR == FNR {                             # while the first file (file2) is read:
  src[FNR] = $1                         # remember the numbers in an array
  next                                  # and we're done
}
{                                       # after that (when processing file1):
  for(i = 1; i <= length(src); ++i) {   # loop through the saved numbers
    printf("%d\t", src[i] - $1)         # subtract the current number from it,
                                        # print result followed by tab
  }
  print ""                              # when done, print a newline
}

编辑:由于问题已被编辑为使用一个文件,其中包含两列而不是两列,每一列都有一个:可以针对该方案稍微调整代码,如下所示:

awk 'NR == FNR && NF > 1 { src[FNR] = $2 } NR != FNR && $1 != "" { for(i = 1; i <= length(src); ++i) { printf("%d\t", src[i] - $1); } print ""; }' file file

这遵循相同的基本模式:在文件上完成两次传递,一次是保存第二列的编号,另一次是计算和打印输出。主要的补充是处理空字段:

NR == FNR && NF > 1 {                    # If this is the first pass and there is
  src[FNR] = $2                          # a second field, remember it
}
NR != FNR && $1 != "" {                  # If this is the second pass and there is
  for(i = 1; i <= length(src); ++i) {    # a first field, process it as before.
    printf("%d\t", src[i] - $1)
  }
  print ""
}

或者,可以按如下方式一次完成:

awk '$1 != "" { a[NR] = $1 } NF > 1 { b[NR] = $2 } END { for(i = 1; i <= length(b); ++i) { for(j = 1; j <= length(a); ++j) { printf("%d\t", b[i] - a[j]) } print "" } }' file

那是:

$1 != "" { a[NR] = $1 }                # If there is a first field, remember it
NF > 1   { b[NR] = $2 }                # If there is a second field, remember it
END {                                  # After reaching the end of the file,
  for(i = 1; i <= length(b); ++i) {    # process the saved data as before.
    for(j = 1; j <= length(a); ++j) {
      printf("%d\t", b[i] - a[j])
    }
    print ""
  }
}
相关问题