我使用perl的Tie::File
来解析.csv文件并匹配特定的字符串,它实际上是文件的第一个字符串/标题。
我遇到的问题可能是我的输入文件类型。导出数据文件的工具可以导出.csv或我试过并测试过的文本。
不知怎的,我仍然没有得到比赛。我的问题可能是双重的: (1)我的正则表达式错误和/或(2)文件类型。
示例文件头/字符串(如果我cat
文件):
??Global Mail_Date.Dat
示例文件头/字符串(如果我在编辑器中打开,Apple的TextEdit.app)
Global Mail_Date.Dat
这是八进制转储:
0000000 377 376 G \0 l \0 o \0 b \0 a \0 l \0 \0
feff 0047 006c 006f 0062 0061 006c 0020
0000020 \0 M \0 a \0 i \0 l \0 _ \0 D \0 a \0
0020 004d 0061 0069 006c 005f 0044 0061
0000040 t \0 e \0 . \0 D \0 a \0 t \0 \r \0 \n \0
0074 0065 002e 0044 0061 0074 000d 000a
显然,执行操作系统cat
会在字符串上显示前导??
。
代码:
use strict;
use warnings;
use Tie::File;
use File::Copy;
for (@ARGV) {
tie my @lines, "Tie::File", $_;
#shift @lines if $lines[0] =~ /^Global/;
if ($lines[0] =~ /^Global/)
{
print "We have a match, remove the line ..";
#shift @lines if $lines[0] =~ /^Global/;
untie @lines;
}
else
{
print "No match found. Exit";
}
}
答案 0 :(得分:1)
看起来你的文件是用utf16编码的。
尝试这样的事情:
binmode STDIN, ':encoding(UTF-16LE)';
while (<STDIN>) {
if (m/Global/) { # see note
print "Matched Global on line $.\n";
}
}
如果你得到一个匹配,那么至少我们知道编码是正确的。
为了补偿BOM代码点,您可以在binmode
调用后读取一个字符:
binmode STDIN, ':encodeing(UTF-16LE)';
read(STDIN, my $buf, 1);
while (<STDIN>) {
if (m/^Global/) { ... }
}
答案 1 :(得分:1)
我正在查看八进制转储并注意每个常规字符之间的空字符。也就是说,它是G-\0-l-\0-o-\0-b-\0-a-\0-l-\0
而不是G-l-o-b-a-l
。这意味着您的文件不是ASCII文本。这是UTF8还是UTF16?如果是这样,则在Perl中打开文件时必须使用encoding
函数:
open(my $fh, "<:encoding(UTF-16)", $fileName)
or die qq(Can't open file "$fileName" for reading);
如果这是csv文件,您应该尝试Text::CSV::Encoded模块。这有助于您解析CSV文件。