下面是我的输入文件,也是我的输出文件。需要帮助读取和写入输入文件。 (PS:输入和输出是同一个文件)
TS_dunit_ PDX_VER_6
TS_test1_par PDX_VER_0
我的代码看起来像下面;
#!/usr/perl/5.14.1
use Getopt::Long;
use strict;
use warnings;
my $file;
GetOptions(
"iofile=s" => \$file
);
if (not defined $file){
print "Please specify input_output (iofile) file\n";
exit;
}
open (my $fh, "$file") or die "Can't open the file $file: ";
open (my $fh1, ">>$file") or die "Can't open the file $file: ";
while (<$fh>){
chomp $_;
next if ($_ !~ /S+/);
$_ =~ /(\S+)\s+(\S+)/;
my $first_underscore =index ($1, '_');
my $dev = substr ($1, $first_underscore + 1,
rindex ($1, '_') - $first_underscore - 1);
my $tag = $2;
my $cat_path = "/testdata/17.26.6/$dev/sd/$tag";
my $arc_path = "archive/$dev/sd/$tag";
if (-d $cat_path){
print $fh1 "$dev $tag IN_CAD\n";
}elsif (-d $arc_path){
print $fh1 "$dev $tag IN_ARCHIVE\n";
}else{
print $fh1 "NA\n";
}
}
print "Done! File been append.\n";
上面的代码将输出显示为
TS_dunit_ PDX_VER_6
TS_test1_par PDX_VER_0
IN_CAD
IN_CAD
无论如何我都需要帮助我可以输出如下。
TS_dunit_ PDX_VER_6 IN_CAD
TS_test1_par PDX_VER_0 IN_CAD
答案 0 :(得分:1)
如果不覆盖文件的其余部分,则无法附加到文件中的某一行。文件是一个字节序列,我们不能插入&#34;插入&#34;新的,只覆盖现有的(或通过扩展文件添加更多)。有关详细信息,请参阅this post。
相反,写出一个新文件,然后将其重命名为原始文件。这确实改变了inode数量;如果你需要保持它看到结束。该代码通过正则表达式简化了index
+ substr
部分。
use warnings;
use strict;
use feature 'say';
use File::Copy qw(mv);
# ... code from the question
open my $fh, '<', $file or die "Can't open $file:$!";
open my $fh_out, '>', $outfile or die "Can't open $outfile:$!";
while (<$fh>)
{
next if not /\S/;
chomp;
my ($dev, $tag) = /.*?_(.*)_\s+(.*)/;
my $cat_path = "/testdata/17.26.6/$dev/sd/$tag";
my $arc_path = "archive/$dev/sd/$tag";
if (-d $cat_path) {
say $fh_out "$_ IN_CAD";
}
elsif (-d $arc_path) {
say $fh_out "$_ IN_ARCHIVE";
}
else {
say $fh_out "NA";
}
}
close $fh;
close $fh_out;
# Changes inode number. See text for comment
move($fh_out, $fh) or die "Can't move $fh_out to $fh: $!";
正则表达式与第一个_
匹配,因为?
使.*?
非贪婪(它首先停在_
)。然后它捕获所有内容,直到上一次 _
,因为.*
是贪婪的,匹配所有内容直到最后_
。这是问题中的代码所使用的rindex
。然后它捕获所有标签/空格。
然后将当前行打印到输出文件中,如问题所示。由于输出文件是临时的,因此应使用File::Temp构建其名称。然后使用File::Copy重命名该文件。
这会更改inode编号。如果这很重要,保持inode编号的一种方法如下。写完输出文件后,打开原始文件进行写入,什么会破坏它。然后从输出文件中读取并写入原始文件。内容被复制到同一个inode。完成后删除输出文件。请参阅开头链接的帖子中的更多详细信息。