parallel: Implemented --files0.

This commit is contained in:
Ole Tange 2023-02-18 23:49:26 +01:00
parent c8e203dfeb
commit e51adc7d7f

View file

@ -88,9 +88,9 @@ sub set_input_source_header($$) {
@opt::filter) { @opt::filter) {
# Skip if undefined # Skip if undefined
$_ or next; $_ or next;
s:\{$s(|/|//|\.|/\.)\}:\{$id$1\}:g; s:\{\Q$s\E(|/|//|\.|/\.)\}:\{$id$1\}:g;
# {=header1 ... =} => {=1 ... =} # {=header1 ... =} => {=1 ... =}
s:$left $s (.*?) $right:$l$id$1$r:gx; s:$left \Q$s\E (.*?) $right:$l$id$1$r:gx;
} }
$Global::input_source_header{$id} = $s; $Global::input_source_header{$id} = $s;
$id++; $id++;
@ -2076,6 +2076,9 @@ sub options_completion_hash() {
"[Remove record separator]" => \$opt::remove_rec_sep), "[Remove record separator]" => \$opt::remove_rec_sep),
("output-as-files|outputasfiles|files[Save output to files]" ("output-as-files|outputasfiles|files[Save output to files]"
=> \$opt::files), => \$opt::files),
("output-as-files0|outputasfiles0|files0".
"[Save output to files separated by NUL]"
=> \$opt::files0),
("block-size|blocksize|block=s". ("block-size|blocksize|block=s".
"[Size of block in bytes to read at a time]:size" "[Size of block in bytes to read at a time]:size"
=> \$opt::blocksize), => \$opt::blocksize),
@ -2206,6 +2209,9 @@ sub parse_options(@) {
if(@opt::v) { $Global::verbose = $#opt::v+1; } # Convert -v -v to v=2 if(@opt::v) { $Global::verbose = $#opt::v+1; } # Convert -v -v to v=2
if($opt::bug) { ::die_bug("test-bug"); } if($opt::bug) { ::die_bug("test-bug"); }
$Global::debug = $opt::D; $Global::debug = $opt::D;
#
## Shell
#
$Global::shell = $ENV{'PARALLEL_SHELL'} || parent_shell($$) $Global::shell = $ENV{'PARALLEL_SHELL'} || parent_shell($$)
|| $ENV{'SHELL'} || "/bin/sh"; || $ENV{'SHELL'} || "/bin/sh";
if(not -x $Global::shell and not which($Global::shell)) { if(not -x $Global::shell and not which($Global::shell)) {
@ -2218,6 +2224,8 @@ sub parse_options(@) {
if(defined $opt::X) { $Global::ContextReplace = 1; } if(defined $opt::X) { $Global::ContextReplace = 1; }
if(defined $opt::silent) { $Global::verbose = 0; } if(defined $opt::silent) { $Global::verbose = 0; }
if(defined $opt::null) { $/ = "\0"; } if(defined $opt::null) { $/ = "\0"; }
if(defined $opt::files) { $Global::files = 1; $Global::files_sep = "\n"; }
if(defined $opt::files0) { $Global::files = 1; $Global::files_sep = "\0"; }
if(defined $opt::d) { $/ = unquote_printf($opt::d) } if(defined $opt::d) { $/ = unquote_printf($opt::d) }
parse_replacement_string_options(); parse_replacement_string_options();
$opt::tag ||= $opt::ctag; $opt::tag ||= $opt::ctag;
@ -2401,7 +2409,7 @@ sub parse_options(@) {
my ($compress, $decompress) = find_compression_program(); my ($compress, $decompress) = find_compression_program();
$opt::compress_program ||= $compress; $opt::compress_program ||= $compress;
$opt::decompress_program ||= $decompress; $opt::decompress_program ||= $decompress;
if(($opt::results and not $Global::csvsep) or $opt::files) { if(($opt::results and not $Global::csvsep) or $Global::files) {
# No need for decompressing # No need for decompressing
$opt::decompress_program = "cat >/dev/null"; $opt::decompress_program = "cat >/dev/null";
} }
@ -2508,6 +2516,10 @@ sub parse_options(@) {
} }
} }
# If you want GNU Parallel to be maintained in the future you
# should keep this.
# *YOU* will be harming free software by removing the notice.
#
# Funding a free software project is hard. GNU Parallel is no # Funding a free software project is hard. GNU Parallel is no
# exception. On top of that it seems the less visible a project # exception. On top of that it seems the less visible a project
# is, the harder it is to get funding. And the nature of GNU # is, the harder it is to get funding. And the nature of GNU
@ -2576,10 +2588,16 @@ sub parse_options(@) {
# If you want GNU Parallel to be maintained in the future you # If you want GNU Parallel to be maintained in the future you
# should keep this line. # should keep this line.
citation_notice(); citation_notice();
# This is because _YOU_ actively make it harder to justify
# spending time developing GNU Parallel by removing it.
# If you disagree, please read (especially 77-):
# https://www.fordfoundation.org/media/2976/roads-and-bridges-the-unseen-labor-behind-our-digital-infrastructure.pdf
# *YOU* will be harming free software by removing the notice. You # *YOU* will be harming free software by removing the notice. You
# accept to be added to a public hall of shame by removing the # accept to be added to a public hall of shame by removing the
# line. This is because _YOU_ actively make it harder to justify # line. That includes you, Andreas and George.
# spending time developing GNU Parallel.
parse_halt(); parse_halt();
@ -5162,6 +5180,7 @@ sub onall($@) {
# $opt::arg_sep # $opt::arg_sep
# $opt::colsep # $opt::colsep
# $opt::files # $opt::files
# $opt::files0
# $opt::group # $opt::group
# $opt::joblog # $opt::joblog
# $opt::jobs # $opt::jobs
@ -5236,6 +5255,7 @@ sub onall($@) {
((defined $opt::arg_sep) ? "--arg-sep ".$opt::arg_sep : ""), ((defined $opt::arg_sep) ? "--arg-sep ".$opt::arg_sep : ""),
((defined $opt::colsep) ? "--colsep ".shell_quote($opt::colsep) : ""), ((defined $opt::colsep) ? "--colsep ".shell_quote($opt::colsep) : ""),
((defined $opt::files) ? "--files" : ""), ((defined $opt::files) ? "--files" : ""),
((defined $opt::files0) ? "--files0" : ""),
((defined $opt::group) ? "--group" : ""), ((defined $opt::group) ? "--group" : ""),
((defined $opt::cleanup) ? "--cleanup" : ""), ((defined $opt::cleanup) ? "--cleanup" : ""),
((defined $opt::keeporder) ? "--keeporder" : ""), ((defined $opt::keeporder) ? "--keeporder" : ""),
@ -9187,7 +9207,7 @@ sub openoutputfiles($) {
# Return immediately because we do not need setting filenames # Return immediately because we do not need setting filenames
return; return;
} elsif($Global::linebuffer and not } elsif($Global::linebuffer and not
($opt::keeporder or $opt::files or $opt::results or ($opt::keeporder or $Global::files or $opt::results or
$opt::compress or $opt::compress_program or $opt::compress or $opt::compress_program or
$opt::decompress_program)) { $opt::decompress_program)) {
# Do not save to files: Use non-blocking pipe # Do not save to files: Use non-blocking pipe
@ -9250,7 +9270,7 @@ sub openoutputfiles($) {
} elsif(not $opt::ungroup) { } elsif(not $opt::ungroup) {
# To group we create temporary files for STDOUT and STDERR # To group we create temporary files for STDOUT and STDERR
# To avoid the cleanup unlink the files immediately (but keep them open) # To avoid the cleanup unlink the files immediately (but keep them open)
if($opt::files) { if($Global::files) {
($outfhw, $outname) = ::tmpfile(SUFFIX => ".par"); ($outfhw, $outname) = ::tmpfile(SUFFIX => ".par");
($errfhw, $errname) = ::tmpfile(SUFFIX => ".par"); ($errfhw, $errname) = ::tmpfile(SUFFIX => ".par");
# --files => only remove stderr # --files => only remove stderr
@ -11103,7 +11123,7 @@ sub print($) {
if($Global::linebuffer) { if($Global::linebuffer) {
# Line buffered print out # Line buffered print out
$self->print_linebuffer($fdno,$in_fh,$out_fh); $self->print_linebuffer($fdno,$in_fh,$out_fh);
} elsif($opt::files) { } elsif($Global::files) {
$self->print_files($fdno,$in_fh,$out_fh); $self->print_files($fdno,$in_fh,$out_fh);
} elsif($opt::results) { } elsif($opt::results) {
$self->print_results($fdno,$in_fh,$out_fh); $self->print_results($fdno,$in_fh,$out_fh);
@ -11328,7 +11348,7 @@ sub print_files($) {
::rm($self->fh($fdno,"unlink")); ::rm($self->fh($fdno,"unlink"));
} }
} elsif($fdno == 1 and $self->fh($fdno,"name")) { } elsif($fdno == 1 and $self->fh($fdno,"name")) {
print $out_fh $self->tag(),$self->fh($fdno,"name"),"\n"; print $out_fh $self->tag(),$self->fh($fdno,"name"), $Global::files_sep;
if($Global::membuffer) { if($Global::membuffer) {
push @{$self->{'output'}{$fdno}}, push @{$self->{'output'}{$fdno}},
$self->tag(), $self->fh($fdno,"name"); $self->tag(), $self->fh($fdno,"name");
@ -11436,7 +11456,7 @@ sub print_files($) {
if($opt::latestline) { $print_later{$self->row()} = $self; } if($opt::latestline) { $print_later{$self->row()} = $self; }
} }
if(not $self->virgin()) { if(not $self->virgin()) {
if($opt::files or ($opt::results and not $Global::csvsep)) { if($Global::files or ($opt::results and not $Global::csvsep)) {
# Print filename # Print filename
if($fdno == 1 and not $self->fh($fdno,"printed")) { if($fdno == 1 and not $self->fh($fdno,"printed")) {
print $out_fh $self->tag(),$self->fh($fdno,"name"),"\n"; print $out_fh $self->tag(),$self->fh($fdno,"name"),"\n";
@ -11573,7 +11593,7 @@ sub print_files($) {
$print_later{$row}->print_latest_line($out_fh); $print_later{$row}->print_latest_line($out_fh);
} }
} }
if($opt::files or ($opt::results and not $Global::csvsep)) { if($Global::files or ($opt::results and not $Global::csvsep)) {
$self->add_returnsize(-s $self->fh($fdno,"name")); $self->add_returnsize(-s $self->fh($fdno,"name"));
} else { } else {
# If the job is dead: print the remaining partial line # If the job is dead: print the remaining partial line