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

Возможно, что-то вдоль этих строк:

udevadm info --export-db | sed  '
  /^E: DEVNAME=/{s///;h;d;}
  /^E:[^=]*LABEL=/!d
  G;s/[^=]*=\(.*\)\n/"\1" /'

udisks эквивалентное существо:

udisks --dump | sed '
  /^[[:blank:]]*device-file:[[:blank:]]*/{s///;h;d;}
  /^[[:blank:]]*label:.*[^[:blank:]]/!d
  G;s/[^:]*:[[:blank:]]*\(.*\)\n/"\1" /'
4
24.06.2014, 16:45
2 ответа

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

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,
3
27.01.2020, 20:56

Вы можете сделать это проще с помощью 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, а значения - это значения coresspond с этими полями.

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

Если вы используете 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 - мы просто сравниваем каждое поле текущей строки со значением coresspond в %h, сохраняя в массиве @diff все различающиеся индексы. карта {$_+1} @diff восстановить номер столбца, потому что индекс массива начинается с 0, номер столбца - с 1.

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

1
27.01.2020, 20:56

Теги

Похожие вопросы