1

我正在处理 2 个大型 CSV 文件。较小的是较大的子集。第一个字段是非唯一键,即 customerID。

我想从较大的文件中找到与较小文件在字段 1 中具有相同值的所有行,然后找到该结果与原始子集之间的增量。

然后,我想从原始子集中删除在增量中存在的字段一中具有值的所有行。

换句话说:我想从原始较小子集中删除任何行,该子集中具有 customerID 也存在于大原始文件中存在的行中,但不存在于较小子集中。

我目前正在这样做,但我不明白为什么结果为 0。

我的逻辑显然存在缺陷,这显然不是最优雅的方法,所以请,我愿意接受更好方法的建议。

文件:完整的.csv

,1052,tec101,UNIX
,1052,ser303,UNIX
,1052,backu2,UNIX
,1052,sma114,UNIX
,1052,appsup,UNIX
,1052,emails,UNIX
,1059,marygs,UNIX
,39835,deepr2,UNIX
,44536,hai499,UNIX
,1274,lemo27,Windows
,48567,wdanro,UNIX
,81860,pro846,UNIX
,1419,graphe,UNIX
,83999,doerf1,UNIX
,1551,taxtri,UNIX
,1572,lodes4,UNIX
,1603,wes244,Windows
,102888,law642,UNIX
,1700,au2960,UNIX

文件:subset.csv

,1052,sma114,UNIX
,1052,appsup,UNIX
,1052,emails,UNIX
,1059,marygs,UNIX
,39835,deepr2,UNIX
,44536,hai499,UNIX
,1274,lemo27,Windows
,48567,wdanro,UNIX
,81860,pro846,UNIX
,1419,graphe,UNIX

我现在在做什么:

[jgalley@linux1 sandbox]$ wc -l *
 19 full.csv
 10 subset.csv
 29 total
[jgalley@linux1 sandbox]$ cat subset.csv |  awk -F, '{print ","$2","}' > subset_keys
[jgalley@linux1 sandbox]$ grep -F -f subset_keys full.csv | wc -l
13
[jgalley@linux1 sandbox]$ grep -F -f subset_keys full.csv | head -n2
,1052,tec101,UNIX
,1052,ser303,UNIX
[jgalley@linux1 sandbox]$ grep -F -f subset_keys full.csv > subset_keys_grep
[jgalley@linux1 sandbox]$ cat subset_keys_grep | awk -F, '{print ","$2","}' | head -n2
,1052,
,1052,
[jgalley@linux1 sandbox]$ cat subset_keys_grep | awk -F, '{print ","$2","}' | wc -l
13
[jgalley@linux1 sandbox]$ cat subset_keys_grep | awk -F, '{print ","$2","}' > keys_to_remove
[jgalley@linux1 sandbox]$ grep -F -f keys_to_remove subset.csv | wc -l
10
[jgalley@linux1 sandbox]$ grep -F -f keys_to_remove subset.csv > lines_to_remove
[jgalley@linux1 sandbox]$ grep -Fv -f lines_to_remove  subset.csv | wc -l
0

我的预期结果应该是 7,或者,如果没有计数,则如下:

,1059,marygs,UNIX
,39835,deepr2,UNIX
,44536,hai499,UNIX
,1274,lemo27,Windows
,48567,wdanro,UNIX
,81860,pro846,UNIX
,1419,graphe,UNIX

结果应该是子集的 7 行,其 customerID 仅存在于子集中,而不存在于完整文件的其他位置。

4

3 回答 3

1

试试这个。我修改了您的输入“full.csv”以删除前 3 行:

$ cat full1.csv
,1052,sma114,UNIX
,1052,appsup,UNIX
,1052,emails,UNIX
,1059,marygs,UNIX
,39835,deepr2,UNIX
,44536,hai499,UNIX
,1274,lemo27,Windows
,48567,wdanro,UNIX
,81860,pro846,UNIX
,1419,graphe,UNIX
,83999,doerf1,UNIX
,1551,taxtri,UNIX
,1572,lodes4,UNIX
,1603,wes244,Windows
,102888,law642,UNIX
,1700,au2960,UNIX

因此,对于 1 个密钥在您的子集.csv 文件中多次出现的情况,您的要求会更好一些。它假定subset.csv 文件中的行顺序与full.csv 文件中的顺序相匹配。如果不是这种情况,则只需进行调整即可拆分字符串...

$ cat test.awk                       
BEGIN{ FS="," }
NR==FNR { key2full[$2] = key2full[$2] $0 ORS; next }
{ key2subset[$2] = key2subset[$2] $0 ORS }
END {
   for (key in key2subset) {
      if (key2subset[key] == key2full[key]) {
         printf "%s", key2subset[key]
      }
   }
}
$ awk -f test.awk full1.csv subset.csv
,1052,sma114,UNIX
,1052,appsup,UNIX
,1052,emails,UNIX
,1419,graphe,UNIX
,44536,hai499,UNIX
,48567,wdanro,UNIX
,1274,lemo27,Windows
,81860,pro846,UNIX
,39835,deepr2,UNIX
,1059,marygs,UNIX

通过在上面修改过的输入文件上运行我的命令,我似乎造成了一些混乱。这里是原始文件,所以这里是针对原始文件运行以显示它确实产生了所需的输出:

$ cat full.csv 
,1052,tec101,UNIX
,1052,ser303,UNIX
,1052,backu2,UNIX
,1052,sma114,UNIX
,1052,appsup,UNIX
,1052,emails,UNIX
,1059,marygs,UNIX
,39835,deepr2,UNIX
,44536,hai499,UNIX
,1274,lemo27,Windows
,48567,wdanro,UNIX
,81860,pro846,UNIX
,1419,graphe,UNIX
,83999,doerf1,UNIX
,1551,taxtri,UNIX
,1572,lodes4,UNIX
,1603,wes244,Windows
,102888,law642,UNIX
,1700,au2960,UNIX

$ awk -f test.awk full.csv subset.csv
,1419,graphe,UNIX
,44536,hai499,UNIX
,48567,wdanro,UNIX
,1274,lemo27,Windows
,81860,pro846,UNIX
,39835,deepr2,UNIX
,1059,marygs,UNIX
于 2012-10-17T15:39:57.013 回答
0

这应该可以解决问题:

grep -v -f subset.csv full.csv | awk -F, '{print ","$2",";}' >keys.csv
grep -v -f keys.csv subset.csv
于 2012-10-17T15:42:30.817 回答
0

根据您的声明,subset.csv 中的所有记录都存在于 full.csv 中,以下应该在 bash 中工作。它首先使用 uniq 从 full.csv 中识别合格的 CustomerID。然后,这只是与子集.csv 合并以进行过滤。

join -o 2.1,2.2,2.3,2.4 -v 2 -t, -1 2 -2 2 <(sort full.csv subset.csv | uniq -u | 
sort -k2,2 -t,) <(sort -k2,2 -t, subset.csv)
于 2012-10-17T16:25:09.397 回答