我想在perl中的文本文件中添加一行,其中包含排序形式的数据。我已经看到了一些示例,它们展示了如何在文件末尾附加数据,但由于我希望数据采用排序格式。
请指导我怎么做。
基本上从我到目前为止所做的尝试: (我打开一个文件,grep它的内容,看看我想要添加到文件的行是否已经存在。如果它确实比退出,则将其添加到文件中(这样数据保持排序格式)
open(my $FH, $file) or die "Failed to open file $file \n";
@file_data = <$FH>;
close($FH);
my $line = grep (/$string1/, @file_data);
if($line) {
print "Found\n";
exit(1);
}
else
{
#add the line to the file
print "Not found!\n";
}
答案 0 :(得分:3)
以下是使用Tie::File的方法,以便您可以轻松地将文件视为数组,List::BinarySearch的bsearch_str_pos
函数可以快速找到插入点。找到插入点后,检查该点的元素是否等于插入字符串。如果不是,splice
进入数组。如果它相等,请不要将其拼接。然后使用untie
完成,以便文件干净地关闭。
use strict;
use warnings;
use Tie::File;
use List::BinarySearch qw(bsearch_str_pos);
my $insert_string = 'Whatever!';
my $file = 'something.txt';
my @array;
tie @array, 'Tie::File', $file or die $!;
my $idx = bsearch_str_pos $insert_string, @array;
splice @array, $idx, 0, $insert_string
if $array[$idx] ne $insert_string;
untie @array;
来自List::BinarySearch的bsearch_str_pos
函数是Mastering Algorithms with Perl的二进制搜索实现的改编版。其方便的特点是,如果找不到搜索字符串,它将返回可以插入的索引点,同时保持排序顺序。
答案 1 :(得分:1)
既然你必须阅读文本文件的内容,那么不同的方法呢?
逐个读取文件中的行,与目标字符串进行比较。如果您读取的行等于目标字符串,则无需执行任何操作。
否则,您最终会根据排序条件读取比当前行“更大”的行,或者您点击文件的末尾。在前一种情况下,您只需将字符串插入该位置,然后复制其余行。在后一种情况下,您将字符串追加到末尾。
如果您不想这样做,可以在@file_data
中进行二进制搜索,找到添加行的位置,而不必检查所有条目,然后将其插入到数组中在将数组输出到文件之前。
答案 2 :(得分:0)
这是一个从stdin(或命令行中指定的文件名)读取的简单版本,如果在输入中找不到,则将'string追加'到输出中。输出打印在标准输出上。
#! /usr/bin/perl
$found = 0;
$append='string to append';
while(<>) {
$found = 1 if (m/$append/o);
print
}
print "$append\n" unless ($found);;
修改它以就地编辑文件(使用perl -i)并从命令行获取追加字符串非常简单。
答案 3 :(得分:0)
在不使用任何模块的情况下插入线条的“简单”单行可以是:
perl -ni -le '$insert="lemon"; $eq=($insert cmp $_); if ($eq == 0){$found++}elsif($eq==-1 && !$found){print$insert} print'
给予list.txt
,其背景为:
ananas
apple
banana
pear
输出是:
ananas
apple
banana
lemon
pear
答案 4 :(得分:0)
{
local ($^I, @ARGV) = ("", $file); # Enable in-place editing of $file
while (<>) {
# If we found the line exactly, bail out without printing it twice
last if $_ eq $insert;
# If we found the place where the line should be, insert it
if ($_ gt $insert) {
print $insert;
print;
last;
}
print;
}
# We've passed the insertion point, now output the rest of the file
print while <>;
}
除了添加了大量可读性之外,与pavel的答案基本相同。请注意,$insert
应该已经包含一个尾随换行符。