【问题标题】:How to keep whitespace formatting while reading a file into an array using perl?使用perl将文件读入数组时如何保持空格格式?
【发布时间】:2021-01-15 19:55:30
【问题描述】:

我正在尝试将文本文件读入行数组,同时保持每行的空白格式。一旦我将整个文件读入一个数组,如果我遍历将所有行打印到 STDOUT 的数组,所有的空白格式以及一些文本都会丢失(查看第一行)。但是,如果我在读取文件时打印这些行,并使用 Data::Dumper 打印数组,则空白格式仍然存在。

由于我试图在遍历数组时捕获 STDOUT 上的输出,请告诉我需要做什么才能打印出正确的空白格式文本。

代码和输出几乎是不言自明的,如下所示。

我在 macOS Mojave 10.14.6 和 Linux Mint 20 之间进行双启动,并且在使用不同版本 perl 的两个系统上遇到相同的问题,版本低于。

提前感谢您的任何建议!!!

macOS:

macOS Mojave 10.14.6
Darwin MBPro.lan 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64

This is perl 5, version 18, subversion 4 (v5.18.4) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)

Linux:

Linux mintMBP 5.4.0-47-generic #51-Ubuntu SMP Fri Sep 4 19:50:52 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

This is perl 5, version 30, subversion 0 (v5.30.0) built for x86_64-linux-gnu-thread-multi
(with 46 registered patches, see perl -V for more detail)

代码如下:

#!/usr/bin/perl

use Data::Dumper;

my $filename = "formatted.txt";
my @lines;

open(my $FH, "<", $filename)
    or die "Can't open < $filename: $!";

print "\nText printed while reading file:\n\n";
while(<$FH>) {
    chomp($_);
    push(@lines, $_);
    print $_ . "\n";
}

close($FH);

print "\nText printed while iterating the line array:\n\n";
while(<@lines>) {
    print $_ . "\n";
}

print "\nText printed using Data::Dumper :\n\n";
print Dumper(@lines);

这是空格格式的输入文件:

<?xml version="1.0" encoding="UTF-8"?>
<dict>
        <key>Definitions</key>
        <dict>
                <key>src/main.c</key>
                <dict>
                        <key>Path</key>
                        <string>src/main.c</string>
                        <key>Group</key>
                        <array>
                                <string>src</string>
                        </array>
                </dict>
        </dict>
</dict>

这是输出:

[MBPro:Development/tmp/perl_formatted_lines] justin% ./file_test.pl

Text printed while reading file:

<?xml version="1.0" encoding="UTF-8"?>
<dict>
    <key>Definitions</key>
    <dict>
        <key>src/main.c</key>
        <dict>
            <key>Path</key>
            <string>src/main.c</string>
            <key>Group</key>
            <array>
                <string>src</string>
            </array>
        </dict>
    </dict>
</dict>

Text printed while iterating the line array:

version=1.0
<dict>
<key>Definitions</key>
<dict>
<key>src/main.c</key>
<dict>
<key>Path</key>
<string>src/main.c</string>
<key>Group</key>
<array>
<string>src</string>
</array>
</dict>
</dict>
</dict>

Text printed using Data::Dumper :

$VAR1 = '<?xml version="1.0" encoding="UTF-8"?>';
$VAR2 = '<dict>';
$VAR3 = '   <key>Definitions</key>';
$VAR4 = '   <dict>';
$VAR5 = '       <key>src/main.c</key>';
$VAR6 = '       <dict>';
$VAR7 = '           <key>Path</key>';
$VAR8 = '           <string>src/main.c</string>';
$VAR9 = '           <key>Group</key>';
$VAR10 = '          <array>';
$VAR11 = '              <string>src</string>';
$VAR12 = '          </array>';
$VAR13 = '      </dict>';
$VAR14 = '  </dict>';
$VAR15 = '</dict>';

【问题讨论】:

  • 不相关的建议:打开文件后,只需执行my @lines=&lt;$FH&gt;; 一次读取所有行,然后执行chomp @lines; 一次将整个数组切碎。
  • 不相关的建议:不要先chomp 行,然后换行\n 回来。另外,不要尝试在没有 XML 解析器的情况下解析 XML。
  • @TedLyngmo 好建议,考虑到这只是整个脚本的一个 sn-p,你没有看到的是从文件中读取的单独处理每一行的代码。
  • Mac::PropertyList 可能对您的大型任务有用。

标签: arrays string file perl


【解决方案1】:

不要使用while (&lt;@lines&gt;),它不会像你想的那样。*

改为使用 for 循环:

for (@lines) {
    print $_, "\n";
}

*) 它调用glob,即将数组的内容与$" 连接起来,并将结果解释为一个全局表达式,即空格分隔的通配符模式。

【讨论】:

  • 感谢您的回答。自从我进行任何真正的 Perl 编程以来已经有好几年了,我什至没有想到它是 while 循环。很高兴我发布了这个问题,因为我的 google-fu 昨晚对我不起作用。
  • 答案中的构造可以用say for @lines代替。
【解决方案2】:

更正了 OP 的演示代码以将行读入数组 @lines

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my $fname = 'formatted.txt';
my @lines;

open my $fh, '<', $fname
    or die "Couldn't open $fname";
    
@lines = <$fh>;

close $fh;

chomp(@lines);

say Dumper(\@lines);
say for @lines;

输入

<?xml version="1.0" encoding="UTF-8"?>
<dict>
        <key>Definitions</key>
        <dict>
                <key>src/main.c</key>
                <dict>
                        <key>Path</key>
                        <string>src/main.c</string>
                        <key>Group</key>
                        <array>
                                <string>src</string>
                        </array>
                </dict>
        </dict>
</dict>

输出

$VAR1 = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<dict>',
          '        <key>Definitions</key>',
          '        <dict>',
          '                <key>src/main.c</key>',
          '                <dict>',
          '                        <key>Path</key>',
          '                        <string>src/main.c</string>',
          '                        <key>Group</key>',
          '                        <array>',
          '                                <string>src</string>',
          '                        </array>',
          '                </dict>',
          '        </dict>',
          '</dict>'
        ];

<?xml version="1.0" encoding="UTF-8"?>
<dict>
        <key>Definitions</key>
        <dict>
                <key>src/main.c</key>
                <dict>
                        <key>Path</key>
                        <string>src/main.c</string>
                        <key>Group</key>
                        <array>
                                <string>src</string>
                        </array>
                </dict>
        </dict>
</dict>

【讨论】:

    猜你喜欢
    • 2019-10-22
    • 2015-12-03
    • 2013-02-09
    • 2011-08-22
    • 2013-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多