我在使用下面的Perl代码时遇到了一些麻烦。我可以打开并阅读我手动制作的CSV文件,但是如果我尝试打开我保存为CSV文件的任何Mac Excel电子表格,下面的代码将其全部读作一行。
#!/usr/bin/perl
use strict;
use warnings;
open F, "file.csv";
foreach (<F>)
{
($first, $second, undef, undef) = split (',', $_);
}
print "$first : $second\n";
close(F);
答案 0 :(得分:10)
为此目的,始终使用专门的模块(例如Text::CSV
或Text::CSV_XS
),因为很多情况下split
- 无效(例如,当字段包含时)逗号,它不是字段分隔符,但在引号内。)
答案 1 :(得分:5)
传统Macintosh(系统9和以前版本)使用CR(0x0D,\ r)作为行分隔符。 Mac OS X(基于Unix)使用LF(0x0A,\ n)作为默认行分隔符,因此作为Unix工具的perl脚本可能期望LF但是正在获得CR。由于perl文件中没有行分隔符,因此认为只有一行。如果它有Windows行结尾(CR,LF),你可能会在每一行的末尾得到一个不可见的CR。
使用0x0A替换0x0D的输入快速循环可以解决您的问题。
答案 2 :(得分:3)
我直接在Excel 2004 for Mac中遇到过这个问题。行结尾确实是\r
,而IIRC,文本使用的是MacRoman字符集,而不是您所期望的Latin-1或UTF-8。
因此,除了使用Text :: CSV / Text :: CSV_XS并在\r
上拆分的好建议之外,您还需要使用MacRoman编码打开文件,如下所示:
open my $fh, "<:encoding(MacRoman)", $filename
or die "Can't read $filename: $!";
同样,在Windows上阅读使用Excel导出的文件时,您可能希望在该代码中使用:encoding(cp1252)
而不是:encoding(MacRoman)
。
答案 3 :(得分:2)
不确定Mac excel,但Windows版本肯定会将所有值括在引号中:"like","this"
。此外,您需要考虑值中引用的可能性,该值会显示"like""this"
(该值中只有一个"
。
然而,要真正回答你的问题,它可能会使用与你期望的不同的换行符。它可能会保存为\r\n
而不是\n
,反之亦然。
答案 4 :(得分:2)
正如其他人所怀疑的那样,你的结局可能是罪魁祸首。在我的基于Linux的系统上,有内置实用程序来更改这些行结尾。 mac2unix
(我认为它只是dos2unix
的包装器会读取你的文件并更改你的行结尾。你应该在Linux和Mac上有类似的东西(微软可能不关心你)。
如果要在Perl中处理此问题,请查看设置$/
变量以将“输入记录分隔符”从“\ n”设置为“\ r”(如果这是正确的结尾)。在阅读文件之前尝试local $/ = "\r"
。请在perldoc perlvar($/
附近)或perldoc perlport中详细了解相关内容(致力于编写可移植的Perl代码。
P.S。如果我有一些不正确的部分让我知道,我不使用Mac,我只是认为我知道理论
答案 5 :(得分:0)
如果你设置“特殊变量”来处理它认为是换行符\ r \ n你将能够一次读取一行:$ / =“\ r”;在这种特殊情况下,perl的mac新行是默认的\ n但文件可能正在使用\ r \ n。这构建了Flynn1179&amp; Mark Thalman说,但是告诉你如何使用while()风格的阅读。