Объясните этот код perl, который отображает общие строки в 2 файлах

Как это относится к линиям с одним слоем для одного слоя, которые имеют 2 файла?

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/'  file1 file2

Ответ 1

Опция командной строки -n преобразует код в нечто, эквивалентное

while ($ARGV = shift @ARGV) {
  open ARGV, $ARGV;
  LINE: while (defined($_ = <ARGV>)) {
    $seen{$_} .= @ARGV;
    print $_ if $seen{$_} =~ /10$/;
  }
}

Пока первый файл читается, scalar @ARGV есть 1. Для каждой строки 1 будет добавлен в запись %seen.

Пока считывается второй файл, scalar @ARGV - 0. Итак, если строка была в файле 1 и в файле2, запись будет выглядеть как 1110000 (это было 3 × в файле1, 4 × в файле2).

Мы хотим только вывести общие строки ровно один раз. Мы делаем это, когда общая строка сначала отображается в файле2, поэтому $seen{$_} - 1110. Это выражается как регулярное выражение /10$/: строка 10 должна появиться в конце.

Ответ 2

@ARGV сдвигается при открытии первого файла. В скалярном контексте он теперь возвращает 1 (потому что он имеет один член, второй файл). Для каждой строки это 1 добавляется к показанному хешу. Когда второй файл открывается, @ARGV снова смещается и теперь пуст, поэтому возвращает 0 в скалярном контексте. /10$/ означает, что строка была видна в файле1, и теперь она впервые была замечена в файле2.