Perl - 格式化输出和读取格式化数据

Posted

技术标签:

【中文标题】Perl - 格式化输出和读取格式化数据【英文标题】:Perl - format output and read formatted data 【发布时间】:2016-05-19 04:35:30 【问题描述】:

我正在尝试将一些数据写入 CSV 文件并读回这些数据。为了更好的可读性,我使用 Perl 格式来创建类似表格的外观,并且为了在 Excel 中打开时将数据显示在适当的列中,我使用逗号分隔列。我的表是具有各自属性的 ID 列表。下面是我用来显示每个 ID 的格式:

format TABLE = 
@<<<<<, ^<<<<<<<<<<<<<<, ^<<<<, @<<<<, @<<<<<
$ID,   $description,    $att,  $errors, $location
      , ^<<<<<<<<<<<<<<, ^<<<<,
       $description,    $att
      , ^<<<<<<<<<<<<<<, ^<<<<,
       $description,    $att
      , ^<<<<<<<<<<<<<<
      $description
      , ^<<<<<<<<<<<<<<
      $description
.

这种格式的问题是保留显示$description$att 的行数是固定的。如果我的字符串比那个长,它将被截断,如果短于 5 行,则总是会显示空行。由于$description 字符串的长度是不可预测的,有没有什么办法可以确保内容即使更长,也不会出现空行,即使它比格式中指定的行数短?

当前输出:

13_456, this is a examp, val1:, 3    , fold1
      , le of a line th, x; va,
      , at if follow th, l2: y,
      , e current forma,
      , t would be trun,

12_456, this is a short, val1:, 0    , fold2
      ,  description   , a; va,
      ,                , l2: b,
      ,                ,
      ,                ,

期望的输出:

13_456, this is a examp, val1:, 3    , fold1
      , le of a line th, x; va,
      , at if follow th, l2: y,
      , e current forma,
      , t would be trun,
      , cated          ,

12_456, this is a short, val1:, 0    , fold2
      ,  description   , a; va,
      ,                , l2: b,

为了从文件中读取,我可以逐行解析文件以匹配$ID 模式并检索该 ID 的所有信息($description$att$errors$location) .但是由于我使用 Perl 格式打印数据,我只是想知道是否可以使用这种格式来读回数据,即 Perl 是否提供任何库/功能来帮助读取符合指定 Perl 格式的数据?我做了一些研究,但似乎没有找到,任何帮助都非常感谢。

【问题讨论】:

你能举一些输入和输出的例子吗?如果您有更复杂的格式要求,我通常建议您查看sprintf 我已经放入了当前和期望输出的示例。我真的不需要复杂的格式化,只是寻找一种可能更灵活的格式化输出的方式,这样我就可以完全显示数据而不会出现空行。 Perl 的format 系统很少使用,我建议你去Perl6::Form 模块,它是Perl 6 形式系统到Perl 5 的向后移植,并且做事“正确” ”。我不知道它是否符合您的要求,这就是为什么这是评论而不是解决方案,但我会尽快看看 【参考方案1】:

自从我上次查看format 以来已经过去了大约五年,但我认为您需要的是自动重复标志~~,它表示应该重新使用格式行,直到变量被清空

您使编写有效的东西变得非常困难,因为您没有给我们任何数据,并且您显示的格式语句无法产生该输出,因为字段宽度不同。你一定也弄乱了$: ($FORMAT_LINE_BREAK_CHARACTERS) 让你的输出像那样拆分,但你没有提到它

除了限制输出的行数之外,这里有一些代码可以生成您所要求的内容。您不能进行多行自动填充以及限制行数,如果超过 75 个字符(5 行15 个字符)

use strict;
use warnings 'all';

my ( $ID, $description, $att, $errors, $location );

format STDOUT =
@<<<<<, ^<<<<<<<<<<<<<<, ^<<<<, @<<<<, @<<<<<
$ID,   $description,    $att,  $errors, $location
      , ^<<<<<<<<<<<<<<, ^<<<<, ~~
       $description,    $att

.

local $:;

( $ID, $description, $att, $errors, $location ) = (
    '13_456',
    'this is a example of a line that if follow the current format would be truncated at the end of the fifth line',
    'val1:x; va12: y',
    3,
    'fold1',
);

write STDOUT;

( $ID, $description, $att, $errors, $location ) = (
    '12_456',
    'this is a shortdescription',
    'val1:a; val2: b',
    3, 'fold2',
);

write STDOUT;

输出

13_456, this is a examp, val1:, 3    , fold1
      , le of a line th, x; va,
      , at if follow th, 12: y,
      , e current forma,      ,
      , t would be trun,      ,
      , cated at the en,      ,
      , d of the fifth ,      ,
      , line           ,      ,

12_456, this is a short, val1:, 3    , fold2
      , description    , a; va,
      ,                , l2: b,

【讨论】:

非常感谢您的回答,这正是我要找的!由于我无法在此处发布我的实际数据,因此我在问题中提出的输出是手工制作和格式化的,仅用于说明目的,如果给您带来任何不便,我深表歉意,我会注意的!再次感谢您的回答! 我意识到发布机密数据可能是不可能的。但是您已经创建了一些可以与代码一起显示的示例数据。我必须从您的输出数据向后工作以创建我认为您的输入的样子,但是我看不出有任何方法可以让 Perl 拆分 this is a short description 而不在 shortdescription 之间放置空格。我已经通过使用this is a shortdescription 来完成它,并将$: 设置为undef,但是当重新创建问题比解决它需要更长的时间时,这是一种耻辱 好的,非常感谢!对于未来的问题,我会听取您的建议!【参考方案2】:

不要试图重新发明***,使用专门用于手头任务的模块:Text::CSV。

【讨论】:

请反对者解释一下他们为什么反对这个?

以上是关于Perl - 格式化输出和读取格式化数据的主要内容,如果未能解决你的问题,请参考以下文章

perl 读取json 格式的文件

Perl:sprintf函数

Perl 读取特定格式的文件名

[ Perl ] 格式化输出时间信息

20200113(数据加载存储和文件格式)

读取 Excel 分段数据,转换,然后输出为数据库的原始格式