Вместо того, чтобы дать вам другой ответ, позвольте мне объяснить вам, что делает ваш пример кода:
while(<>){chomp;/^[^@]+@([^@]+)$/;$h{$1}++;}
foreach $k (sort { $h{$b} <=> $h{$a} } keys %h) {print $h{$k}." ".$k."\n";}
Первая строка подсчитывает домены из писем в файлах.
while(<>)
перебирает входные файлы построчно. Входные файлы - это файл (ы), переданные в качестве аргументов, или стандартный ввод, если аргументы не переданы. Каждая строка помещается в $_
.
chomp;
просто удаляет символ новой строки в конце $_
.
/^[^@]+@([^@]+)$/
- это регулярное выражение, которое анализирует домен и применяется к $_
. Он проверяет что-то, что не имеет «@» в первой части, затем «@», а затем «@» в последней части. Он запоминает последнюю часть, которая будет сохранена в $1
. ^
и $
означают начало и конец строки соответственно.
$h{$1}++;
использует домен (в $1
) для увеличения счетчика в хэше %h
. Это работает, даже если его нет, потому что undef
ведет себя здесь как 0.
Чтобы сделать эту работу для вашего списка, вы можете просто сделать
foreach(@emails) {/^[^@]+@([^@]+)$/;$h{$1}++;}
Вторая строка печатает домены из хеша %h
.
sort { $h{$b} <=> $h{$a} } keys %h
возвращает список доменов, отсортированных по убыванию, с помощью функции сравнения $h{$b} <=> $h{$a}
для просмотра количества. Обратите внимание, что это b <=> a, а не <=> b, это делает его убывающим.
Остальная часть строки 2 выводит результат.