目前我有以下脚本
#!/usr/bin/env perl
use strict;
use warnings;
my %seen;
my $header = <> . <>;
print $header;
my $last_sequence_number = 0;
open( my $output, ">", "output.$last_sequence_number.out" ) or die $!;
print {$output} $header;
$seen{$last_sequence_number}++;
while (<>) {
my ($key) = split;
next unless $key =~ m/^\d+$/;
my $sequence_number = int( $key / 1000 );
if ( not $sequence_number == $last_sequence_number ) {
print "Opening new file for $sequence_number\n";
close($output);
open( $output, ">", "output.$sequence_number.out" ) or die $!;
print {$output} $header unless $seen{$sequence_number}++;
$last_sequence_number = $sequence_number;
}
print {$output} $_;
}
脚本将文件拆分为带有模式文件1文件2的其他文件...现在我需要向脚本传递另一个参数,该参数允许为输出指定前缀,因此如果此附加输入为{{1那么输出就是
1
,1_file1
....等等......我怎么能这样做?
我知道像
这样的东西1_file2
可以用吗?
尝试了这个
use Getopt::Long;
但这不起作用。有什么问题?
我得到了
#!/usr/bin/env perl
use strict;
use warnings;
my %seen;
my $header = <> . <>;
print $header;
my ( $suffix, $filename ) = @ARGV;
open ( my $input, "<", $filename ) or die $!;
my $last_sequence_number = 0;
open( my $output, ">", "output.$last_sequence_number.out" ) or die $!;
print {$output} $header;
$seen{$last_sequence_number}++;
while (<$input>) {
my ($key) = split;
next unless $key =~ m/^\d+$/;
my $sequence_number = int( $key / 1000 );
if ( not $sequence_number == $last_sequence_number ) {
print "Opening new file for $sequence_number\n";
close($output);
open( $output, ">", "output.$sequence_number.out" ) or die $!;
print {$output} $header unless $seen{$sequence_number}++;
$last_sequence_number = $sequence_number;
}
print {$output} $_;
}
打印标题后。
答案 0 :(得分:2)
正如Sobrique所说,你的问题是<>
的神奇本质。但我认为这并不像他想的那样难以应对。
重点是<>
查看@ARGV
的当前值。因此,只要您确保在首次使用@ARGV
之前已将其从<>
中删除,就可以添加其他命令行参数。
所以改变你的代码,使它像这样开始:
my %seen;
my $prefix = shift;
my $header = <> . <>;
然后你可以这样调用你的程序:
$ your_program.pl prefix_goes_here list of file names...
其他所有内容现在应该与目前相同,但您的前缀存储在$prefix
中,以便您可以在print
语句中使用它。
我希望这就是你想要的。你的问题不是特别清楚。
答案 1 :(得分:1)
我会做这样的事情。
#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
use Getopt::Long qw(:config bundling);
use Pod::Usage;
{
my $man = 0;
my $help = 0;
my $verbose = 0;
my $prefix = '';
my $suffix = '';
my $header_lines = 2;
my $bunch_size = 1000;
GetOptions(
'help|?' => \$help,
'man' => \$man,
'verbose|v+' => \$verbose,
'prefix|p=s' => \$prefix,
'suffix|s=s' => \$suffix,
'header|h=i' => \$header_lines,
'bunch|batch|bucket|b=i' => \$bunch_size
) or pod2usage(2);
pod2usage(1) if $help;
pod2usage( -exitval => 0, -verbose => 2 ) if $man;
pod2usage(
-exitval => 3,
-message => "Headers lines can't be negative number"
) if $header_lines < 0;
pod2usage(
-exitval => 4,
-message => "Bunch size has to be positive"
) unless $bunch_size > 0;
my $header = '';
$header .= <> for 1 .. $header_lines;
my %seen;
my $current_output_number = -1;
sub key2output { int( shift() / $bunch_size ) }
sub set_output {
my $output_number = shift;
if ( $output_number != $current_output_number ) {
my $seen = $seen{$output_number}++;
printf STDOUT "Opening %sfile for %d\n", $seen ? '' : 'new ',
$output_number
if $verbose;
open my $fh, $seen ? '>>' : '>',
$prefix . $output_number . $suffix;
select $fh;
print $header unless $seen;
$current_output_number = $output_number;
}
}
}
while (<>) {
my ($key) = /^(\d+)\s/;
next unless defined $key;
set_output( key2output($key) );
print;
}
__END__
=head1 NAME
code.pl - splits file by first number by thousands
=head1 SYNOPSIS
code.pl [options] [file ...]
Options:
--help brief help message
--man full documentation
--prefix output filename prefix
--suffix outpit filename suffix
--header number of header lines (default: 2)
=head1 OPTIONS
=over 8
=item B<--help>
Print a brief help message and exits.
=item B<--man>
Prints the manual page and exits.
=back
=head1 DESCRIPTION
B<This program> will read the given input file(s) and do something
useful with the contents thereof.
=cut
只需完成文档,您就可以将其发送给您的同事。
答案 2 :(得分:0)
你遇到的问题是钻石操作员<>
是一种特殊的perl魔法。
'命令行上的所有文件名'打开它们并按顺序处理它们。
要做你想做的事情:
my ( $suffix, $filename ) = @ARGV;
open ( my $input, "<", $filename ) or die $!;
然后您可以将while循环更改为:
while ( <$input> ) {
根据您的需要修改输出文件名。关键不同的是,它只需要一个文件名 - 第一个arg是后缀,第二个是名称。
您可以通过以下方式扩展它:
my ( $suffix, @names ) = @ARGV;
然后运行foreach循环:
foreach my $filename ( @names ) {
open .... #etc