比较两个CSV文件的字段内的拆分字符串

时间:2014-06-13 02:27:49

标签: csv awk

我有一个CSV文件(file1),如下所示:

123,info,ONE NAME
124,info,ONE VARIATION
125,info,NAME ANOTHER
126,info,SOME TITLE

和另一个CSV文件(file2)如下所示:

1,info,NAME FIRST
2,info,TWO VARIATION
3,info,NAME SECOND
4,info,ANOTHER TITLE

我想要的输出是:

1,123,NAME FIRST,ONE NAME
3,125,NAME SECOND,NAME ANOTHER

如果NAME的逗号分隔字段3中的第一个单词(即第1行中的file2)等于file1字段3中的任何单词,则打印a格式为:

field1(file2),field1(file1),field3(file2),field3(file1)

每个文件的行数相同,只有当每个文件具有相同的行号时才会进行匹配。

我知道我可以分割字段并在awk中的field3中获取第一个单词:

awk -F"," '{split($3,a," "); print a[1]}' file

但是因为我在Awk中只能适度胜任,所以我对如何处理有两个文件的作业感到茫然。

我可以用Python这样做:

with open('file1', 'r') as f1, open('file2', 'r') as f2:
    l1 = f1.readlines()
    l2 = f2.readlines()
    for i in range(len(l1)):
        line_1 = l1[i].split(',')
        line_2 = l2[i].split(',')
        field_3_1 = line_1[2].split()
        field_3_2 = line_2[2].split()
        if field_3_2[0] in field_3_1:
            one = ' '.join(field_3_1)
            two = ' '.join(field_3_2)
            print(','.join((line_2[0], line_1[0], two, one)))

但是我想知道如何在Awk中完成这样的工作,因为偶尔我会使用只有Awk可用的shell。

这似乎是一项需要做的奇怪任务,我认为我的例子可能有点令人困惑,但我需要执行此操作来检查其中一个文件中是否存在损坏/格式错误的数据。

3 个答案:

答案 0 :(得分:2)

awk -F, -vOFS=, '
{
  num1 = $1
  name1 = $3
  split(name1, words1, " ")
  getline <"file2"
  split($3, words2, " ")
  for (i in words1)
    if (words2[1] == words1[i]) {
      print $1, num1, $3, name1
      break
    }
}
' file1

输出:

1,123,NAME FIRST,ONE NAME
3,125,NAME SECOND,NAME ANOTHER

答案 1 :(得分:1)

你可以尝试一下,尽管以下内容只为第二个文件中的每一行打印一个匹配项:

 awk -F, 'FNR==NR {
    count= split($3, words, " ");
    for (i=1; i <= count; i++) { 
        field1hash[words[i]]=$1; 
        field3hash[$1]=$3; 
    }
    next;
  }
  {
     split($3,words," "); 
     if (field1hash[words[1]]) { 
         ff1 =  field1hash[words[1]]; 
         print $1","ff1","$3","field3hash[ff1]
      }
  }' file1 file2

答案 2 :(得分:1)

我更喜欢@ ooga的答案:

awk -F, -v OFS=, '
    NR==FNR {
        split($NF, a, " ")
        data[NR,"word"] = a[1]
        data[NR,"id"] = $1
        data[NR,"value"] = $NF
        next
    }
    {
        n = split($NF, a, " ")
        for (i=1; i<=n; i++)
            if (a[i] == data[FNR,"word"])
                print data[FNR,"id"], $1, data[FNR,"value"], $NF
    }
' file2 file1