如何使用 Perl 将零添加到我的文件中以使行长度相同?
How to add zeros into my file using Perl to make lines the same length?
我是 Perl 的新手,我有一个看起来像这样的文本文件,其中一行包含一个整数,后跟两行包含由制表符分隔的数字列表 \t
.这只是文件的一个示例,它重复了这个整数序列和 2 行数字列表。
1
1.10E-40 0.000970842 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
2
8.96E-11 0.066251575 0.025529498 0.00084864
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
我想使用 Perl 使包含数字列表的每一行都包含相同数量的数字(在本例中为 6 个数字),因此我想在末尾插入由制表符分隔的零少于 6 个数字的行。不过,我不想对包含单个整数的行执行此操作。
基本上,我希望输出看起来像这样:
1
1.10E-40 0.000970842 0 0 0 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
2
8.96E-11 0.066251575 0.025529498 0.00084864 0 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
所以每行有 6 个数字(每三行中的第一行除外,我只想包含一个整数)。我在想,也许这可以通过一个字数统计工具来实现,该工具可以告诉我每行有多少个数字,然后以某种方式将 0\t
附加到每一行相关的次数。我什至不确定是否可以附加到文件的特定行。
我也不太确定如何计算文件一行的字数(反正我以前从来没有计算过字数),但是当我查找字数统计代码时,我看到它看起来像这样:
open(FILE, "<file.txt") or die "Could not open file: $!";
my ($words) = (0);
while (<FILE>) {
$words += scalar(split(/\s+/, $_));
}
print("words=$words");
但是我必须承认,我并不真正理解这是如何计算单词的机制,所以我真的不知道这是否符合正确的思路,是否可以调整以计算每一行。那里有一个 'split' 的事实让我觉得它可能会分成几列,我认为这不是我想要的。
你可以这样做:
#!/usr/bin/env perl
use strict;
use warnings;
while (<>) # read lines from STDIN
my @line = split; # create an array of fields
my $flds = scalar @line; # get number of fields
if ( $flds == 1 ) { # print rows with one column, unaltered
print;
next;
}
print join "\t", @line; # separate each field with a tab
print "\t0" for ( 1 .. (6 - $flds) ); # add a tab and a zero, needed times
print "\n"; # print the modified line
}
要使用,请执行以下操作:
try.pl < try.data
UPDATE 用于:有没有办法将其硬编码到我的脚本中?
如果您希望将输入和输出文件名嵌入到此脚本中,请执行以下操作:
#!/usr/bin/env perl
use strict;
use warnings;
my $filein = "try.data";
my $fileout = "try.filtered";
open( my $fin, '<', $filein ) or die "Can't open '$filein : $!\n";
open( my $fout, '>', $fileout ) or die "Can't open '$fileout: $!\n";
select $fout; # set as default output filehandle
while (<$fin>) {
my @line = split; # create an array of fields
my $flds = scalar @line; # get number of fields
if ( $flds == 1 ) { # print rows with one column, unaltered
print;
next;
}
print join "\t", @line; # separate each field with a tab
print "\t0" for ( 1 .. (6 - $flds) ); # add a tab and a zero, needed times
print "\n"; # print the modified line
}
现在,运行 为:
try.pl
根据 OP 问题描述,想到以下脚本
#!/usr/bin/env perl
#
# vim: ai ts=4 sw=4
use strict;
use warnings;
my $columns = 6;
while( <DATA> ) {
my @data = split;
push @data, (0) x ($columns - @data) unless @data == 1;
print join("\t", @data) . "\n";
}
exit 0;
__DATA__
1
1.10E-40 0.000970842 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
2
8.96E-11 0.066251575 0.025529498 0.00084864
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
输出
1
1.10E-40 0.000970842 0 0 0 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
2
8.96E-11 0.066251575 0.025529498 0.00084864 0 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
我是 Perl 的新手,我有一个看起来像这样的文本文件,其中一行包含一个整数,后跟两行包含由制表符分隔的数字列表 \t
.这只是文件的一个示例,它重复了这个整数序列和 2 行数字列表。
1
1.10E-40 0.000970842 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
2
8.96E-11 0.066251575 0.025529498 0.00084864
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
我想使用 Perl 使包含数字列表的每一行都包含相同数量的数字(在本例中为 6 个数字),因此我想在末尾插入由制表符分隔的零少于 6 个数字的行。不过,我不想对包含单个整数的行执行此操作。 基本上,我希望输出看起来像这样:
1
1.10E-40 0.000970842 0 0 0 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
2
8.96E-11 0.066251575 0.025529498 0.00084864 0 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
所以每行有 6 个数字(每三行中的第一行除外,我只想包含一个整数)。我在想,也许这可以通过一个字数统计工具来实现,该工具可以告诉我每行有多少个数字,然后以某种方式将 0\t
附加到每一行相关的次数。我什至不确定是否可以附加到文件的特定行。
我也不太确定如何计算文件一行的字数(反正我以前从来没有计算过字数),但是当我查找字数统计代码时,我看到它看起来像这样:
open(FILE, "<file.txt") or die "Could not open file: $!";
my ($words) = (0);
while (<FILE>) {
$words += scalar(split(/\s+/, $_));
}
print("words=$words");
但是我必须承认,我并不真正理解这是如何计算单词的机制,所以我真的不知道这是否符合正确的思路,是否可以调整以计算每一行。那里有一个 'split' 的事实让我觉得它可能会分成几列,我认为这不是我想要的。
你可以这样做:
#!/usr/bin/env perl
use strict;
use warnings;
while (<>) # read lines from STDIN
my @line = split; # create an array of fields
my $flds = scalar @line; # get number of fields
if ( $flds == 1 ) { # print rows with one column, unaltered
print;
next;
}
print join "\t", @line; # separate each field with a tab
print "\t0" for ( 1 .. (6 - $flds) ); # add a tab and a zero, needed times
print "\n"; # print the modified line
}
要使用,请执行以下操作:
try.pl < try.data
UPDATE 用于:有没有办法将其硬编码到我的脚本中?
如果您希望将输入和输出文件名嵌入到此脚本中,请执行以下操作:
#!/usr/bin/env perl
use strict;
use warnings;
my $filein = "try.data";
my $fileout = "try.filtered";
open( my $fin, '<', $filein ) or die "Can't open '$filein : $!\n";
open( my $fout, '>', $fileout ) or die "Can't open '$fileout: $!\n";
select $fout; # set as default output filehandle
while (<$fin>) {
my @line = split; # create an array of fields
my $flds = scalar @line; # get number of fields
if ( $flds == 1 ) { # print rows with one column, unaltered
print;
next;
}
print join "\t", @line; # separate each field with a tab
print "\t0" for ( 1 .. (6 - $flds) ); # add a tab and a zero, needed times
print "\n"; # print the modified line
}
现在,运行 为:
try.pl
根据 OP 问题描述,想到以下脚本
#!/usr/bin/env perl
#
# vim: ai ts=4 sw=4
use strict;
use warnings;
my $columns = 6;
while( <DATA> ) {
my @data = split;
push @data, (0) x ($columns - @data) unless @data == 1;
print join("\t", @data) . "\n";
}
exit 0;
__DATA__
1
1.10E-40 0.000970842 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
2
8.96E-11 0.066251575 0.025529498 0.00084864
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
输出
1
1.10E-40 0.000970842 0 0 0 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27
2
8.96E-11 0.066251575 0.025529498 0.00084864 0 0
2.51E-27 5.89E-07 0.132602458 0.020980783 2.89E-05 1.37E-27