Perl错误地添加换行符?

时间:2013-10-08 04:05:57

标签: perl

这是我的制表符分隔输入文件

Name<tab>Street<tab>Address

这就是我希望输出文件看起来像

的样子
Street<tab>Address<tab>Address

(是的,重复下两列)我的输出文件看起来像这样

Street<tab>Address
         <tab>Address

perl发生了什么?这是我的代码。

open (IN, $ARGV[0]);

open (OUT, ">output.txt");
while ($line = <IN>){

    chomp $line;
    @line=split/\t/,$line;

    $line[2]=~s/\n//g;
   print OUT $line[1]."\t".$line[2]."\t".$line[2]."\n";
}

close( OUT);

4 个答案:

答案 0 :(得分:4)

首先,您应始终

  • use strictuse warnings即使是最琐碎的计划也是如此。您还需要使用my尽可能接近第一次使用来声明每个变量

  • 使用词法文件句柄和open

  • 的三参数形式
  • 检查每次 open来电是否成功,并die使用包含$!的字符串来查看失败的原因

另请注意,无需显式打开@ARGV中显示的命令行上命名的文件:您只需使用<>读取它们。

正如其他人所说,看起来你正在Linux系统上读取DOS或Windows源文件。您可以使用chomp从每行中删除所有尾随空格字符,而不是使用s/\s+\z//。由于CR和LF都算作“空白”,这将从每条记录中删除所有行终止符。但是,请注意,如果尾随空格很重要或者最后一个字段可能为空,那么这也将删除空格和制表符。在这种情况下,s/[\r\n]+\z//更合适。

此版本的程序运行正常。

use strict;
use warnings;

@ARGV = 'addr.txt';

open my $out, '>', 'output.txt' or die $!;

while (<>) {
  s/\s+\z//;
  my @fields = split /\t/;
  print $out join("\t", @fields[1, 2, 2]), "\n";
}

close $out or die $!;

答案 1 :(得分:2)

如果你事先知道 数据文件的来源,并且知道它是一个类似DOS的文件来终止CR LF的记录,你可以使用PerlIO打开文件时的crlf图层。喜欢这个

open my $in, '<:crlf', $ARGV[0] or die $!;

然后,当在Linux系统上读取所有记录时,所有记录都将以"\n"结尾。

此问题的一般解决方案是安装PerlIO::eol。然后你可以写

open my $in, '<:raw:eol(LF)', $ARGV[0] or die $!;

,无论文件的来源如何,始终的行始终都是"\n",无论Perl运行的平台如何。

答案 2 :(得分:0)

您是否尝试不仅消除“\ n”而且还消除“\ r”???

$file[2] =~ s/\r\n//g;
$file[3] =~ s/\r\n//g; # Is it the "good" one?

它可以工作。 DOS行结尾也可以是“\ r”(不仅是“\ n”)。

答案 3 :(得分:0)

避免行尾问题的另一种方法是仅捕获您感兴趣的字符:

open (IN, $ARGV[0]);

open (OUT, ">output.txt");
while (<IN>) {
    print OUT "$1\t$2\t$2\n" if /^(\w+)\t\w+\t(\w+)\s*/;
}

close( OUT);