这是我的制表符分隔输入文件
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);
答案 0 :(得分:4)
首先,您应始终
use strict
和use 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);