linux - 用于查找两个文件的列之和的差异的脚本

标签 linux bash unix scripting

我有一些记录的两个文件

   rec10|rec11|rec12|....|abcd1234|rec19|rec110|rec111|name1|xyz|.......|rec1n
   rec20|rec21|rec22|....|abcd1234|rec29|rec210|rec211|name1|xyz|.......|rec2n
   rec30|rec31|rec32|....|xyzw1234|rec39|rec310|rec311|name1|uvw|.......|rec3n
   ...........................................................................
   ...........................................................................

Some columns are key columns which i can cut and put in another file (say keyFile)

  cat recordFile|cut -d"|", -f1,5,7 >keyFile

现在对于 keyFile 中的每个键 K,我必须过滤以 K 为键的行并获得按列求和

我需要为 recordFile2 做同样的事情

我想要键和列的区别

假设文件 1 是

x,y,z,5,6,7
a,y,z,3,5,8
a,x,t,1,1,1

文件2是

x,y,s,1,2,3
p,y,z,3,5,8
a,y,z,1,1,1

假设第 2 列和第 3 列是键列,如果我剪切这些列,则不同的键是 (y,z) (x,t) (y,s) 对于每个键,我需要找出列式总和的差异

说(y,z) 我可以加起来得到 8,11,15 同样对于文件 2 得到 4,6,9 和差异是 4,5,6 所以输出是 (y,z) 4 5 6

其他键也类似

while read line  //read one key each time from inKeyFile
       IFS=', ' read -a array <<< "$line"
       for element in "${array[@]}"
       do

// filter rows which matched whole key array .**How to put the filter condition in awk for complete key value in array**
<code>
       IFS=' ' read -a arrayA<<<  awk -F"|" -v k="$num1" -v n="$num2" '$col1=array[0] && $col2=array[1]&& so on.. {for(i=k;i<=n;i++)s[i]+=$i} END{for(x in s)printf " %f ",s[x]}' recordFile1

      //read the awk output into an array A of size num2-num1+1
    //same for Recordsfile2 to read in an array B
      IFS=' ' read -a arrayB<<<  awk .....
     print line-->(the key)
      for(i=num1 to num2) print $A[i] -$B[i]

<<inKeyFile  

我如何将过滤器放入 awk 中,假设我将其作为 ./Myscript.sh inFile 2:x,3:y,5:z 10 15 运行 具有第 10 列到第 15 列的列总和,其中键列具有指定值 第 2、3、5 列是关键列(我可以将它们剪切并放入 KeyFile 中),第 2 列应为 x,第 3 列应为 y,第 5 列应为 z。如何在 awk 中应用此过滤器?

如何避免处理 inKeyFile 中已经打印差异的键(类似于 Java 中的 Set)? 编辑:我想我可以对 inKeyFile 进行排序,如果上次读取的 key 与当前 key 相同,那么我可以跳过

最佳答案

求差 file1 - file2 作为按选定列分组的行总和的差,例如,12(零-基于):

$ ./columnwise-sum-diff 1,2 file1 file
{"y|z": [4, 5, 6]}

其中 columnwise-sum-diff 是:

#!/usr/bin/env python
import json
import sys
from operator import itemgetter

def columnwise_sum(a, b):
    return tuple(x+y for x, y in zip(a, b)) # map(sum, zip(*args))

def columnwise_diff(a, b):
    return tuple(y-x for x, y in zip(a, b)) # b - a

def sum_file(filename, get_key, get_numbers):
    filesum = {}
    with open(filename) as file:
        for line in file:
            row = line.split(',')
            key = get_key(row)
            numbers = get_numbers(row)
            total = filesum.get(key)
            filesum[key] = columnwise_sum(total, numbers) if total else numbers
    return filesum

if len(sys.argv) != 4:
    sys.exit('Usage: columnwise-sum-diff <keycol1,keycol2> <file1> <file2>')

key_columns = sorted(map(int, sys.argv[1].split(',')))
get_key = itemgetter(*key_columns)
n = max(key_columns) + 1 # to the right of the key columns

def get_numbers(row, getcols=itemgetter(*range(n, n + 3))):
    return tuple(map(int, getcols(row)))

file1sum = sum_file(sys.argv[2], get_key, get_numbers)
file2sum = sum_file(sys.argv[3], get_key, get_numbers)
diff = {'|'.join(k): columnwise_diff(file2sum[k], file1sum[k])
        for k in file1sum.viewkeys() & file2sum.viewkeys()}
json.dump(diff, sys.stdout)

它生成 json 以简化结构化数据交换。

关于linux - 用于查找两个文件的列之和的差异的脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27650496/

相关文章:

Linux - 如何在不提取内容并再次应用 tar 的情况下重命名 .tgz 文件中的文件?

c++ - 在 Unix 上编译所有的 boost 库?

java - 如何在 Java 中为 exec 方法的参数指定文件夹?

c - 在这两个函数中为什么需要执行WATCHDOG_RESET()?

java - 从 java 执行命令时使用 bash 函数

linux - IntelliJ IC Linux 中是否可以进行外部拖放或复制/粘贴?

linux - 如果同一个文件中存在 CR 和 LF,sed 无法区分它们

unix - Groff 图像在同一行?

c++ - UART 上的串行数据被损坏

c++ - Valgrind 在 ATI 上运行 opengl 程序时报告很多错误 - 我应该担心吗?