当前位置:  开发笔记 > 编程语言 > 正文

如何在Perl中读取固定长度的记录?

如何解决《如何在Perl中读取固定长度的记录?》经验,为你挑选了3个好方法。

在Perl中读取固定长度记录的最佳方法是什么.我知道要读取如下文件:

ABCDE 302
DEFGC 876

我可以

while () {
   $key = substr($_, 0, 5);
   $value = substr($_, 7, 3);
}

但是没有办法用read/unpack做到这一点?



1> Jonathan Lef..:
my($key, $value) = unpack "A5 A3";    # Original, but slightly dubious

我们都需要查看解压缩手册页面中的选项(更具体地说,包装手册页).

由于A pack运算符删除了尾随空白,因此您的示例可以编码为:

my($key, $value) = unpack "A6A3";

或者(这是Perl,所以TMTOWTDI):

my($key, $blank, $value) = unpack "A5A1A3";

1是可选的,但系统和对称.这样做的一个优点是您可以验证这一点$blank eq " ".



2> runrig..:

更新:有关最终答案,请参阅Jonathan Leffler在下面的回答.

我不会在两个字段中使用它(我直接使用pack/unpack),但对于20或50个左右的字段,我喜欢使用Parse :: FixedLength(但我有偏见).例如(对于你的例子)(更新:同样,你可以使用$ /和<>作为读取的替代方法($ fh,$ buf,$ buf_length)...见下文):

use Parse::FixedLength;

my $pfl = Parse::FixedLength->new([qw(
  key:5
  blank:1
  value:3
)]);
# Assuming trailing newline
# (or add newline to format above and remove "+ 1" below)
my $data_length = $pfl->length() + 1;

{
  local $/ = \$data_length;
  while() {
    my $data = $pfl->parse($_);
    print "$data->{key}:$data->{value}\n";
    # or
    print $data->key(), ":", $data->value(), "\n";
  }
}

有一些类似的模块使打包/解包更"友好"(参见Parse :: FixedLength的"另请参阅"部分).

更新:哇,这本来是一个替代答案,而不是正式答案......好吧,因为它就是这样,我应该包括一些Jonathan Leffler的更直接的代码,这很可能你应该通常这样做(请参阅下面的打包/解压缩文档和Jonathan Leffler的节点):

$_ = "ABCDE 302";
my($key, $blank, $value) = unpack "A5A1A3";



3> Michael Cram..:

假设每条记录有两个五个字符字段的10个字符记录:

open(my $fh, "<", $filename) or die $!;
while(read($fh, $buf, 10)) {
  ($field1, $field2) = unpack("A5 A5", $buf);
  # ... do something with data ...
}

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有