更新文件第一列的值并继续追加 n 次
Update a value of the first column of a file and keep appending n times
我正在寻找一种更好的方法来在文件的第一列的内容上添加 2,并继续追加 n 次。这可以是一个单行程序。
输入文件(sparc_test.export,实际文件超过3000行):
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rcc_data_e[6]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[51]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[3]
20000 cmp_top.iop.sparc0.exu.alu.shft_alu_shift_out_e[18]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[17]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[43]
预期的输出文件(假设它运行 3 次):
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rcc_data_e[6]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[51]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[3]
20000 cmp_top.iop.sparc0.exu.alu.shft_alu_shift_out_e[18]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[17]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[43]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rcc_data_e[6]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[51]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[3]
20002 cmp_top.iop.sparc0.exu.alu.shft_alu_shift_out_e[18]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[17]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[43]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rcc_data_e[6]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[51]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[3]
20004 cmp_top.iop.sparc0.exu.alu.shft_alu_shift_out_e[18]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[17]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[43]
在第一列中添加 2 的单行 perl 代码是:
perl -pe 's/(\d+)/ + 2/e' sparc_export.test
所以,我使用这段代码并追加 (<<) 3 次,但似乎不太好,我认为有一个更好的方法是使用单行代码。任何帮助表示赞赏。
我的 perl 代码 (test.pl)
#!/usr/bin/perl
use strict;
use warnings;
my $fin;
my $foutput;
for (my $i=0; $i < 3; $i++) {
open $fin, '<', 'sparc_export.test' or die "Can't open file: $!";
open $fout, '>>', 'sparc_export.test.out' or die "Can't open file: $!";
while (<$fin>) {
s/(\d+)/ + 2/e;
print $fout $_;
}
close $fout;
close $fin;
rename 'sparc_export.test.out', 'sparc_export.test' or die "Failed to rename: $!";
system $bin, @args;
}
唯一缺少的部分是您没有先复制输入文件。 (嗯,为什么是 C 风格的 for 循环?)
不过,您也可以避免额外的文件操作——读入一个数组并使用它。
use warnings;
use strict;
my $infile = 'sparc_export.test';
open my $fh, '<', $infile or die "Can't open $infile: $!";
my @lines = <$fh>;
my $outfile = 'sparc_export.test.out';
open $fh, '>>', $outfile or die "Can't open for append $outfile: $!";
print $fh $_ for @lines; # copy the original first
for my $i (1..3)
{
s/^\s*(\d+)/+2/e for @lines; # changes @lines in place
print $fh $_ for @lines;
}
close $fh;
# now overwrite source
或者全部在内存中完成并更新一次原始文件,因为文件很小。使用 Path::Tiny
use warnings;
use strict;
use Path::Tiny;
my @lines = path('sparc_export.test')->lines;
my @all_lines = @lines;
push @all_lines, map { s/(\d+)/+100/e; $_ } @lines for 1..3;
path('sparc_export.test')->append( {truncate => 1}, @all_lines );
append
和 truncate
选项附加替换内容。
或
my @lines = path('sparc_export.test')->lines;
my @new_lines = map {
map { s/(\d+)/+100/e; $_ } @lines
} 1..3;
path('sparc_export.test')->append( @new_lines );
我看不出单线有什么更好的,除非它是一个特定的要求。
我正在寻找一种更好的方法来在文件的第一列的内容上添加 2,并继续追加 n 次。这可以是一个单行程序。
输入文件(sparc_test.export,实际文件超过3000行):
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rcc_data_e[6]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[51]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[3]
20000 cmp_top.iop.sparc0.exu.alu.shft_alu_shift_out_e[18]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[17]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[43]
预期的输出文件(假设它运行 3 次):
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rcc_data_e[6]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[51]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[3]
20000 cmp_top.iop.sparc0.exu.alu.shft_alu_shift_out_e[18]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[17]
20000 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[43]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rcc_data_e[6]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[51]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[3]
20002 cmp_top.iop.sparc0.exu.alu.shft_alu_shift_out_e[18]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[17]
20002 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[43]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rcc_data_e[6]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[51]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[3]
20004 cmp_top.iop.sparc0.exu.alu.shft_alu_shift_out_e[18]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rs3_data_e[17]
20004 cmp_top.iop.sparc0.exu.alu.byp_alu_rs1_data_e[43]
在第一列中添加 2 的单行 perl 代码是:
perl -pe 's/(\d+)/ + 2/e' sparc_export.test
所以,我使用这段代码并追加 (<<) 3 次,但似乎不太好,我认为有一个更好的方法是使用单行代码。任何帮助表示赞赏。
我的 perl 代码 (test.pl)
#!/usr/bin/perl
use strict;
use warnings;
my $fin;
my $foutput;
for (my $i=0; $i < 3; $i++) {
open $fin, '<', 'sparc_export.test' or die "Can't open file: $!";
open $fout, '>>', 'sparc_export.test.out' or die "Can't open file: $!";
while (<$fin>) {
s/(\d+)/ + 2/e;
print $fout $_;
}
close $fout;
close $fin;
rename 'sparc_export.test.out', 'sparc_export.test' or die "Failed to rename: $!";
system $bin, @args;
}
唯一缺少的部分是您没有先复制输入文件。 (嗯,为什么是 C 风格的 for 循环?)
不过,您也可以避免额外的文件操作——读入一个数组并使用它。
use warnings;
use strict;
my $infile = 'sparc_export.test';
open my $fh, '<', $infile or die "Can't open $infile: $!";
my @lines = <$fh>;
my $outfile = 'sparc_export.test.out';
open $fh, '>>', $outfile or die "Can't open for append $outfile: $!";
print $fh $_ for @lines; # copy the original first
for my $i (1..3)
{
s/^\s*(\d+)/+2/e for @lines; # changes @lines in place
print $fh $_ for @lines;
}
close $fh;
# now overwrite source
或者全部在内存中完成并更新一次原始文件,因为文件很小。使用 Path::Tiny
use warnings;
use strict;
use Path::Tiny;
my @lines = path('sparc_export.test')->lines;
my @all_lines = @lines;
push @all_lines, map { s/(\d+)/+100/e; $_ } @lines for 1..3;
path('sparc_export.test')->append( {truncate => 1}, @all_lines );
append
和 truncate
选项附加替换内容。
或
my @lines = path('sparc_export.test')->lines;
my @new_lines = map {
map { s/(\d+)/+100/e; $_ } @lines
} 1..3;
path('sparc_export.test')->append( @new_lines );
我看不出单线有什么更好的,除非它是一个特定的要求。