【问题标题】:Understand Error in Perl script理解 Perl 脚本中的错误
【发布时间】:2026-01-04 00:50:02
【问题描述】:

我正在尝试编写一个 Perl 脚本来转换存储在文件夹中的某些 CSV 文件的行尾。我是 Perl 新手,因此我们将不胜感激。

use strict;
use warnings;

my @files = glob "*.csv";

foreach my $i (@files) {

    system('perl -i.bak -pe "s/\R/\n/g" '.$i.'') or die "$?";

}

转换第一个文件后,脚本终止并出现以下错误:

0 at script_conversione_linebreaks.pl at line 8.

这是进行转换的正确方法吗?或者我必须在系统语句中一次传递所有 CSV 文件?

【问题讨论】:

  • 第一个问题是 - 您实际上想要完成什么?您提到您希望在之后处理文件 - 因此实际上很有可能不需要单独进行转换。
  • @RobEarl 的建议很有用
  • 也许使用dos2unix 或类似的会更好?

标签: perl csv line-breaks


【解决方案1】:

关于你的错误信息,因为system的返回值是程序的状态,如果程序成功你会得到0。这意味着您将die,因为0 被解释为假。

use strict;
use warnings;

my @files = glob "*.csv";

foreach my $i (@files) {
    system('perl -i.bak -pe "s/\R/\n/g" ' . $i) and die "$?"; # Note the `and`
}

进一步通知:您正在为每个 csv 文件运行一个子进程。这在性能方面很糟糕。您可能需要考虑从 shell 运行单个命令:

perl -i.bak -pe 's/\R/\n/g' *.csv

但我认为在这种情况下你应该选择另一种武器。

这有帮助吗?

#!/bin/sh
for i in *.csv; do cp $i $i.bak; dos2unix $i; done

编辑: 正如@AkHolland 在评论中指出的那样,您可以直接在所有文件上直接调用dos2unix,并让它在它们上循环。这不会生成备份,但dos2unix 也确实不会出错文本文件

【讨论】:

  • 我很想投票。无需重新发明*。
  • Tnx 的建议。我从未使用过dos2unix,我会尝试一下。顺便说一下,我想知道如何解决 Perl 执行中的错误。
  • dos2unix 如果您不小心在非文本文件上运行它,将会出现严重错误。
  • @cjm,已修复。另外我认为 perl 单行也会出错 XD
【解决方案2】:

我会使用@Dacav 的解决方案,但是您程序中的错误是system 返回被调用的可执行文件的退出代码,而0 在这里表示成功。

所以

system "something" or die $?;

应该是

system "something" == 0  or die $?;

由于这是您大部分时间想要的,Perl 有一个编译指示可以自动检查 system 和朋友的错误代码:

use autodie qw(:all);

将此添加到您的程序中,您将获得异常,而不必检查返回码。

【讨论】:

  • 有趣的autodie 事情。我不知道这一点。
【解决方案3】:

一个班轮 perl 怎么样:

perl -p -i -e 's/\R/\n/g' path/to/files/*.csv

【讨论】:

  • 我需要对转换后的CSV数据进行操作,所以我使用了脚本而不是命令行。 Tnx。
  • 如果你这样做,你可能根本不需要转换。
  • 我没有找到解决方案来逐行读取未转换的 CSV 文件。它被作为一个完整的字符串读取。
  • 尝试更改输入记录分隔符:$/ = "\R";
  • @RobEarl tnx。这是一个非常有用的。