我正在通过CGI在perl中读取文本文件,并注意到当文件保存在mac的textEdit中时,行分隔符被识别,但是当我上传直接从excel导出的CSV时,它们不是。我猜这是一个\ n与\ r \ n问题,但它让我觉得我不知道如何指定我想要的行终止符令牌,如果我不想要它正在寻找的那个默认情况下。
答案 0 :(得分:4)
是。您需要覆盖$/
的值。来自perlvar
$ /
输入记录分隔符,默认为换行符。这影响了Perl关于“线”是什么的想法。像awk的RS变量一样工作,包括将空行设置为终止符(如果设置为空字符串)。 (空行不能包含任何空格或制表符。)您可以将其设置为多字符字符串以匹配多字符终结符,或者设置为undef以读取文件末尾。将其设置为“\ n \ n”意味着与设置为“”略有不同,如果文件包含连续的空行。设置为“”会将两个或多个连续的空行视为一个空行。设置为“\ n \ n”将盲目地假设下一个输入字符属于下一段,即使它是换行符。 (助记符:/在引用诗歌时划界线边界。)
local $/; # enable "slurp" mode local $_ = <FH>; # whole file now here s/\n[ \t]+/ /g;
请记住:$ /的值是字符串,而不是正则表达式。 awk必须更好的东西。 : - )
将$ /设置为对整数的引用,包含整数的标量或可转换为整数的标量将尝试读取记录而不是行,最大记录大小为引用的整数。所以这个:
local $/ = \32768; # or \"32768", or \$var_containing_32768 open my $fh, "<", $myfile or die $!; local $_ = <$fh>;
将从FILE中读取不超过32768字节的记录。如果您没有从面向记录的文件中读取(或者您的操作系统没有面向记录的文件),那么每次读取时您都可能获得完整的数据块。如果记录大于您设置的记录大小,您将获得记录。尝试将记录大小设置为零或更小将导致读取整个文件的(其余部分)。
在VMS上,记录读取是使用等效的sysread完成的,因此最好不要在同一文件上混合记录和非记录读取。 (这不太可能是一个问题,因为您想要以记录模式读取的任何文件在线路模式下可能无法使用。)非VMS系统执行正常的I / O,因此混合记录和非记录读取是安全的一个文件。
另请参阅perlport中的“Newlines”。另见$ ..
答案 1 :(得分:2)
该变量有多个名称:
$/
$RS
$INPUT_RECORD_SEPARATOR
对于较长的名字,您需要:
use English;
请记住仔细本地化:
{
local($/) = "\r\n";
...code to read...
}
答案 2 :(得分:1)
如果您正在使用CRLF行终止符读取文件,则可以使用CRLF规则打开它,或者设置句柄的binmode以进行自动转换。
open my $fh, '<:crlf', 'the_csv_file.csv' or die "Oh noes $!";
这会将\r\n
序列透明地转换为\n
序列。
您还可以通过执行以下操作将此翻译应用于现有句柄:
binmode( $fh, ':crlf' );
:crlf
模式通常是Win32 Perl环境中的默认模式,在实践中运行良好。
答案 3 :(得分:0)
要阅读CSV文件,请遵循Robert-P在其注释中的建议,并使用CSV模块。
但是对于从具有不同行尾的文件中读取行的一般情况,我通常要做的是将文件完整地封装并在\R
上分割。如果它不是数千兆字节的文件,那应该是最安全,最简单的方法。
所以:
perl -0777 -nle 'my @lines = split /\R/;
print length($_), " bytes split into ", scalar(@lines), " lines."' $YOUR_FILE
或在您的脚本中:
{
local $/ = undef;
open F, $YOUR_FILE or die;
@lines = split /\R/, <F>;
close F;
}
\R
适用于Unix LF(\x0A
),Windows / Internet CRLF,也适用于90年代Mac所使用的CR(\x0D
),但实际上仍然被某些Mac程序使用。
来自perldoc:
\ R匹配通用换行符;也就是说,任何被认为是换行符的东西 Unicode序列。这包括\ v匹配的所有字符 (垂直空白)和多字符序列“ \ x0D \ x0A” (回车后跟换行符,有时也称为网络 新队;这是Microsoft文本文件中使用的行序列的结尾 以二进制模式打开)
或者在Brian D Foy的文章The \R generic line ending中看到有关\R
的更详尽,详尽的解释,甚至还有一些有趣的视频。