Perl 从文件中隔离特定的列但是当一列中有特殊字符时不起作用
Perl isolating specific columns from file but doesnt work when there is special characters in one column
我写了一个脚本来将特定列从 1 个文件隔离到一个新文件。它在大多数情况下都按预期工作,但是,当我的数据文件的其中一列中有 / 时,以下脚本将不起作用,只有 returns 1 行。
For example,
A B C D E
1 2 3 4 /sb/home/
1 3 4 5 /sb/home/
The script will only return
1 2 3 +
Without the E column, it returns everything as intended.
1 2 3 +
1 3 4 +
use strict;
use warnings;
my ($file1, $file2) = @ARGV;
open my $fh1, '<', $file1;
open my $fh2, '>', $file2;
while (<$fh1>) {
my @columns = split /\t/, $_;
print {$fh2} "$columns[0]\t$columns[1]\t$columns[2]\t+\n";
}
close $fh1;
close $fh2 or die $!;
关于为什么会发生这种情况以及解决方法的任何想法?
我把你的程序改成了这个来测试:
#! /usr/bin/env perl
#
use strict;
use warnings;
my ($file1, $file2) = @ARGV;
while (<DATA>) {
my @columns = split /\t/, $_;
print "$columns[0]\t$columns[1]\t$columns[2]\t+\n";
}
__DATA__
1 2 3 4 /sb/home/
1 3 4 5 /sb/home/
我得到:
1 2 3 +
1 3 4 +
我怀疑问题出在您的输入文件上。 Perl 读取 NL,如果文件在 NL 之前结束,您可能无法读取最后一行。检查你的文件。确保最后一行以 NL 结尾,看看是否有帮助。
几点建议:
- 使用
use autodie;
或在打开文件时检查。关闭文件时这样做并不重要。
- 拆分时,最好使用
split /\s+/, $string;
,因为/\s+/
表示任意数量的空格或制表符。如果出于某种原因有人将两个制表符连成一行,或使用了空格,它仍然有效。
您在“\t”上拆分,但您的列由空格或“\s”分隔
改变
my @columns = split /\t/, $_;
到
my @columns = split /\s/, $_;
此外,正如 David 所说,检查您的行结尾并确保每行以 "new line" 结尾,否则 Perl 可能无法正确处理它。
我写了一个脚本来将特定列从 1 个文件隔离到一个新文件。它在大多数情况下都按预期工作,但是,当我的数据文件的其中一列中有 / 时,以下脚本将不起作用,只有 returns 1 行。
For example,
A B C D E
1 2 3 4 /sb/home/
1 3 4 5 /sb/home/
The script will only return
1 2 3 +
Without the E column, it returns everything as intended.
1 2 3 +
1 3 4 +
use strict;
use warnings;
my ($file1, $file2) = @ARGV;
open my $fh1, '<', $file1;
open my $fh2, '>', $file2;
while (<$fh1>) {
my @columns = split /\t/, $_;
print {$fh2} "$columns[0]\t$columns[1]\t$columns[2]\t+\n";
}
close $fh1;
close $fh2 or die $!;
关于为什么会发生这种情况以及解决方法的任何想法?
我把你的程序改成了这个来测试:
#! /usr/bin/env perl
#
use strict;
use warnings;
my ($file1, $file2) = @ARGV;
while (<DATA>) {
my @columns = split /\t/, $_;
print "$columns[0]\t$columns[1]\t$columns[2]\t+\n";
}
__DATA__
1 2 3 4 /sb/home/
1 3 4 5 /sb/home/
我得到:
1 2 3 +
1 3 4 +
我怀疑问题出在您的输入文件上。 Perl 读取 NL,如果文件在 NL 之前结束,您可能无法读取最后一行。检查你的文件。确保最后一行以 NL 结尾,看看是否有帮助。
几点建议:
- 使用
use autodie;
或在打开文件时检查。关闭文件时这样做并不重要。 - 拆分时,最好使用
split /\s+/, $string;
,因为/\s+/
表示任意数量的空格或制表符。如果出于某种原因有人将两个制表符连成一行,或使用了空格,它仍然有效。
您在“\t”上拆分,但您的列由空格或“\s”分隔
改变
my @columns = split /\t/, $_;
到
my @columns = split /\s/, $_;
此外,正如 David 所说,检查您的行结尾并确保每行以 "new line" 结尾,否则 Perl 可能无法正确处理它。