有一个像下一个名为"input.txt"的文本文件
some field1a | field1b | field1c
...another approx 1000 lines....
fielaNa | field Nb | field Nc
Run Code Online (Sandbox Code Playgroud)
我可以选择任何字段分隔符.
需要一个脚本,每个离散运行的内容将从该文件中获得一个唯一(从不重复)的随机行,直到使用所有行.
我的解决方案:我在文件中添加了一列,所以有
0|some field1a | field1b | field1c
...another approx 1000 lines....
0|fielaNa | field Nb | field Nc
Run Code Online (Sandbox Code Playgroud)
并使用下一个代码处理它:
use 5.014;
use warnings;
use utf8;
use List::Util;
use open qw(:std :utf8);
my $file = "./input.txt";
#read all lines into array and shuffle them
open(my $fh, "<:utf8", $file);
my @lines = List::Util::shuffle map { chomp $_; $_ } <$fh>;
close $fh;
#search for the 1st line what has 0 at the start
#change the 0 to 1
#and rewrite the whole file
my $random_line;
for(my $i=0; $i<=$#lines; $i++) {
if( $lines[$i] =~ /^0/ ) {
$random_line = $lines[$i];
$lines[$i] =~ s/^0/1/;
open($fh, ">:utf8", $file);
print $fh join("\n", @lines);
close $fh;
last;
}
}
$random_line = "1|NO|more|lines" unless( $random_line =~ /\w/ );
do_something_with_the_fields(split /\|/, $random_line))
exit;
Run Code Online (Sandbox Code Playgroud)
这是一个有效的解决方案,但不是很好,因为:
如何写得更有效,更优雅?
该程序使用该Tie::File模块来打开您的input.txt文件以及indices.txt文件。
如果indices.txt为空,则使用所有记录的索引以input.txt打乱的顺序对其进行初始化。
每次运行,列表末尾的索引都会被删除,并显示相应的输入记录。
use strict;
use warnings;
use Tie::File;
use List::Util 'shuffle';
tie my @input, 'Tie::File', 'input.txt'
or die qq(Unable to open "input.txt": $!);
tie my @indices, 'Tie::File', 'indices.txt'
or die qq(Unable to open "indices.txt": $!);
@indices = shuffle(0..$#input) unless @indices;
my $index = pop @indices;
print $input[$index];
Run Code Online (Sandbox Code Playgroud)
更新
indices.txt我修改了此解决方案,以便仅在新文件尚不存在时才填充新文件,而不是像以前那样仅在文件为空时填充新文件。这意味着只需删除文件即可打印新的记录序列indices.txt。
use strict;
use warnings;
use Tie::File;
use List::Util 'shuffle';
my ($input_file, $indices_file) = qw( input.txt indices.txt );
tie my @input, 'Tie::File', $input_file
or die qq(Unable to open "$input_file": $!);
my $first_run = not -f $indices_file;
tie my @indices, 'Tie::File', $indices_file
or die qq(Unable to open "$indices_file": $!);
@indices = shuffle(0..$#input) if $first_run;
@indices or die "All records have been displayed";
my $index = pop @indices;
print $input[$index];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
984 次 |
| 最近记录: |