chomp
удаляет один \n
символ из конца строки.
Если строка заканчивается на \r\n
(конец строки в стиле Windows), chomp
оставит \r
на месте. Это может привести к появлению симптомов, похожих на то, что вы видите.
EDIT :
Некоторый фон. Unix-подобные системы (включая Linux) используют один символ перевода строки ('\n'
), чтобы отметить конец каждой строки в текстовом файле. Windows (и ее предшественник MS-DOS) используют два символа: возврат каретки и перевод строки (\r\n
).
Многие функции Perl предназначены для работы с текстом. Это означает, что вполне разумно, что Perl предполагает по умолчанию, что любой текстовый файл, который он читает, использует собственное представление конца строки базовой операционной системы.
Особенность Perl, унаследованная от C, заключается в том, что при чтении строки текста нативная последовательность конца строки, какой бы она ни была, транслируется в один '\n'
символ. (Обратный перевод делается на выходе). Это освобождает большинство программ от необходимости беспокоиться о том, как представлен текст; это переведено в и из канонической внутренней формы на входе и выходе. (По историческим причинам эта форма соответствует формату Unix.)
Но это мало поможет, если вам нужно иметь дело с не родными текстовыми файлами. Если вы работаете в Unix-подобной среде, но читаете текстовые файлы в формате Windows, символы \r
будут выглядеть как часть строки. В частности, chomp
не будет делать с ними ничего особенного. И когда вы печатаете символ \r
, это обычно приводит к перемещению курсора в начало текущей строки без перехода к следующей строке. Это беспорядок. (Cygwin является богатым источником такой путаницы; это Unix-подобная среда, использующая текстовые файлы в стиле Unix по умолчанию, но она работает под Windows с полной видимостью файловой системы Windows. Вы используете Cygwin?)
См. Комментарий @ BillRupert; он работает под Windows с собственной версией Windows для Perl, поэтому он не видит проблемы, с которой вы столкнулись.
Если вы хотите работать с не родными текстовыми файлами, вам нужно проделать небольшую дополнительную работу. Например, при чтении строки текста, а не просто
chomp $line;
Вы можете написать:
chomp $line;
$line =~ s/\r$//;
А при написании текста вы можете сделать это:
$line =~ s/$/\r/;
Но сначала вам нужно решить, хотите ли вы записать вывод с окончаниями строк в стиле Windows или Unix. Это сложно.
(Вероятно, существует модуль Perl, который облегчает эту задачу; всем, кто его знает, просьба упомянуть об этом в комментарии.)
Кстати, вывод, который вы видите, не тот, который выдает ваша программа. Если вы отфильтруете свой вывод по чему-то, что показывает непечатаемые символы в печатной форме, вы увидите \r
или ^M
в своем выводе. Используйте ... | cat -A
или ... | cat -v
, если ваша система имеет команду cat
.
Если возможно, вы можете подумать о переводе ввода, прежде чем пытаться его прочитать.