Сравнение файлов в unix по столбцам

Сравнение файлов в unix по столбцам

Я хочу сравнить два файла с одинаковым количеством строк и столбцов с записями в том же порядке. Просто хочу выделить различия в значениях столбцов, если таковые имеются.

file A:

1,kolkata,19,ab

2,delhi,89,cd

3,bangalore,56,ef

file B:

1,kolkata,21,ab

2,mumbai,89,gh

3,bangalore,11,kl

Рассматривая столбец 1как первичный ключ, у нас есть различия в других столбцах. Я хочу подчеркнуть эти различия.

Формат вывода может быть (не уверен):

record_number,  columns_with_diff
1               3

2               2,4

3               3,4

Может ли diffили commрешить мою проблему? Если да, то какая будет точная команда?

решение1

Вот это да. Просто какая-то проблема со стилем, с дополнительной запятой в конце каждой строки.

awk '
     BEGIN{ FS=","; ORS="" }

     { 
       # read line from secondary file
       getline aux < "file2"
       split(aux,f2,",")

       # print current line number
       print NR" "

       # process each field in current line
       for(i=1; i<=NF; i++) {
         if ($i!=f2[i]) {
           print i","
         }
       }
       print "\n"
     }
' file1

Выход:

1 3,
2 2,4,
3 3,4,

решение2

Вы можете сделать это проще с помощью perl:

$ perl -F',' -anle '
    BEGIN{
        print "record_number,  columns_with_diff";
        $" = ",";
    }
    if (!defined($h{$.})) {
        @{$h{$.}}{0..$#F} = @F[0..$#F];
    } else {
        @diff =  grep { $h{$.}{$_} ne $F[$_] } 0..$#F;
        print "$.\t\t@{[map {$_+1} @diff]}";
    } 
    close ARGV if eof;
' file1 file2
record_number,  columns_with_diff
1       3
2       2,4
3       3,4

Для этого вам следует удалить пустые строки из входных данных.

Объяснение

  • В BEGINблоке мы просто печатаем заголовок вывода, затем устанавливаем разделитель списка на,

  • @{$h{$.}}{0..$#F} = @F[0..$#F]: мы создаем хеш хешей, где ключами первого хеша являются номера строк, ключами каждого подхеша являются индексы полей минус 1, а значениями являются значения, соответствующие этим полям.

Здесь мы используем хэш-срез для быстрого присвоения значений хэшу хэшей.

если вы используете Data::Dumperдля печати хэш хэшей %h, вы можете увидеть что-то вроде этого:

VAR1 = {
          '2' => {
                   '2' => '89',
                   '0' => '2',
                   '1' => 'delhi',
                   '3' => 'cd'
                 },
          '3' => {
                   '1' => 'bangalore',
                   '3' => 'ef',
                   '0' => '3',
                   '2' => '56'
                 },
          '1' => {
                   '3' => 'ab',
                   '1' => 'kolkata',
                   '0' => '1',
                   '2' => '19'
                 }
        };
  • Если мы создали %h( if (!defined($h{$.}))) - то есть завершили обработку file1- мы просто сравниваем каждое поле текущей строки с соответствующим значением в %h, сохраняя все индексы, которые отличаются, в массиве @diff. map {$_+1} @diffВосстанавливаем номер столбца, поскольку индекс массива начинается с 0, номер столбца начинается с 1.

  • close ARGV if eofвосстановить $.счетчик.

Связанный контент