как сравнить значения между двумя файлами? - PullRequest
0 голосов
/ 25 января 2019

У меня есть два файла с двумя столбцами, разделенными пробелом

cat file1.txt
281475225437349 33,32,21,17,20,22,18,30,19,16,23,31
281475550885480 35,32,33,21,39,40,57,36,41,17,20,38,34,37,16,99

cat file2.txt
281475550885480 16,17,20,21,32,33,34,35,36,37,38,39,40,41
281475225437349 16,17,18,19,20,21,22,23,24,25,30,31,32,33

Я хочу сравнить значения из file1 column2 с file2 column2 для того же значения в column1.и печатать только те значения, которые существуют в file1 column2, но не в file2 column2, а не наоборот, вместе с соответствующим значением в column1

Желаемое o / p

, оно не должно ничего печатать для 281475225437349поскольку все значения из file1 column2 присутствуют в file2 column 2 для 281475225437349

, он должен печатать только значения для 281475550885480, которые присутствуют в file1 column2, но отсутствуют в file2 column2.Например, значения 57 и 99 для 281475550885480

Итак, файл o / p, например:

cat output.txt
281475550885480 57,99

Я попытался отсортировать файл и сравнить с помощью sdiff, но это дает разницу и время, необходимое для этого

sdiff file1.txt file2.txt

Ответы [ 6 ]

0 голосов
/ 25 января 2019

еще awk

$ awk -v c=, 'NR==FNR {a[$1]=$2; next}
                      {for(i=2;i<=NF;i++) 
                         {if(c a[$1] c !~ c $i c) p=(p==""?$1" ":p c) $i} 
                          if(p) print p; p=""}' file2 FS=' |,' file1

281475550885480 57,99
0 голосов
/ 25 января 2019
$ cat tst.awk
BEGIN { FS="[ ,]" }
NR==FNR {
    for (i=2; i<=NF; i++) {
        file2[$1,$i]
    }
    next
}
{
    diff = ""
    for (i=2; i<=NF; i++) {
        if ( !(($1,$i) in file2) ) {
            diff = (diff == "" ? "" : diff ",") $i
        }
    }
    if (diff != "") {
        print $1, diff
    }
}

$ awk -f tst.awk file2 file1
281475550885480 57,99
0 голосов
/ 25 января 2019

Это может сработать для вас (GNU sed):

sed -r 's#^(\S+)\s(\S+)$#/^\1 /s/$/,\\n\2,/#' file2 |
sed -rnf - -e ':a;s/(\b[0-9]+,)(.*\n.*)\1/\2/;ta;s/(.*),\n.*/\1/p' file1

Решение можно разделить на две части.

Первый файл2 превращается в сценарий sed, который добавляет значения для каждого ключа к одному и тому же ключу в файле1.Дополнительные , добавлены для упрощения сопоставления и будут служить индикатором того, есть ли у строки из файла1 значения для печати. ​​

Сценарий, сгенерированный из файла2, передается во второй вызов sed и дополнительныйнижний индекс использует подстановку и цикл для удаления совпадающих значений из file1.

Если совпадение не удалось, и поскольку второй вызов sed использует переключатель -n, чтобы сделать печать явной, при окончательном совпадении удаляется введенный ,и несоответствующие значения после новой строки и выводят требуемый результат.

0 голосов
/ 25 января 2019

Это просто с awk:

awk '(NR==FNR) { a[$1]=","$2","; next }
     { delete b }                   # clear array for new run
     { split($2,f,",") }            # split string of file1 in array f
     { for(i in f) if (! match(a[$1],"," f[i] ",")) b[f[i]]  }                                                                                                                                                                             
     { c=$1" "; for(i in b) {printf c i; c="," }; if (c==",") printf "\n" }' file2 file1

, который возвращает:

281475550885480 57,99

Идея состоит в том, чтобы сохранить строку второго столбца с дополнительными двумя , чтобы гарантировать, что каждое число находится между запятыми. Затем найдите подстроку с запятой.

Если вам нужно проверить действительные числа, и вам, возможно, придется сравнить числа «5» с «005», и они должны быть равны, то вам следует сделать следующее:

awk '(NR==FNR) { a[$1]=$2; next }
     { delete b }                       # clear array
     { # split strings in number elements
       split($2,f,",");    for(i in f) f1[f[i]+0];
       split(a[$1],f,","); for(i in f) f2[f[i]+0]
     }
     { for(i in f1) if (! (i in f2)) b[i] }
     { c=$1" "; for(i in b) {printf c i; c="," }; if (c==",") printf "\n" }' file2 file1
0 голосов
/ 25 января 2019

Решение Perl: создайте хэш хэшей из второго файла. Ключ - большое число, внутренние ключи - меньшие числа из списка через запятую. Затем выполните итерацию по первому файлу и проверьте, какие числа не упоминаются в запомненной структуре.

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

open my $f1, '<', 'file1' or die $!;
open my $f2, '<', 'file2' or die $!;

my %seen;
while (<$f2>) {
    my ($key, $value_string) = split ' ';
    my @values = split /,/, $value_string;  #/
    undef @{ $seen{$key} }{@values};
}
while (<$f1>) {
    my ($key, $value_string) = split ' ';
    my @values = split /,/, $value_string;
    my %surplus;
    undef @surplus{@values};
    delete @surplus{ keys %{ $seen{$key} } };
    say $key, ' ', join ',', keys %surplus
        if keys %surplus;
}

Кстати, когда вы переключаете файлы, вывод будет

281475225437349 24,25

потому что 24 и 25 отсутствуют в file1.

0 голосов
/ 25 января 2019

Вы должны использовать два цикла в вашем коде.Также разделите символ ',' и установите два массива после

foreach(var itemOne as arrayOne){
boolean isExist=false;
foreach(var itemTwo as arrayTwo)
if(itemOne==itemTwo) isExist=true;

if(isExist) console.log(itemOne+" is exist");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...