diff --git a/src/parallel b/src/parallel index af2b8ed2..a4ee96eb 100755 --- a/src/parallel +++ b/src/parallel @@ -4507,7 +4507,7 @@ sub number_of_replacements { my $multi_regexp = multi_regexp(); my $replacement_regexp = "(?:". ::maybe_quote('\{') . - '\d+(?:|\.|/\.|/|//)?' . # {n} {n.} {n/.} {n/} {n//} + '-?\d+(?:|\.|/\.|/|//)?' . # {n} {n.} {n/.} {n/} {n//} {-n} {-n.} {-n/.} {-n/} {-n//} ::maybe_quote('\}') . '|'. join("|",map {$a=$_;$a=~s/(\W)/\\$1/g; $a} values %Global::replace). @@ -4647,7 +4647,7 @@ sub context_replace_placeholders { # Normal replace strings my $rep_str_regexp = multi_regexp(); # Positional replace strings - my $rep_str_pos_regexp = ::maybe_quote('\{').'\d+'.$rep_inner_regexp.::maybe_quote('\}'); + my $rep_str_pos_regexp = ::maybe_quote('\{').'-?\d+'.$rep_inner_regexp.::maybe_quote('\}'); # Fish out the words that have replacement strings in them my $tt = $target; @@ -4673,8 +4673,9 @@ sub context_replace_placeholders { } else { @argset = @{$self->{'arg_list'}}; } - # Match 1..n where n = max args in a argset - my $pos_regexp = "(?:".join("|", 1 .. $#{$argset[0]}+1).")"; + # Match -n..-1,1..n where n = max args in a argset + my $n = $#{$argset[0]}+1; + my $pos_regexp = "(?:".join("|", -$n..-1, 1..$n).")"; my $pos_inner_regexp = ::maybe_quote('\{') . "($pos_regexp)($rep_inner_regexp)" . ::maybe_quote('\}'); @@ -4689,7 +4690,9 @@ sub context_replace_placeholders { } } $w = $word; - $w =~ s/$pos_inner_regexp/$argset->[$1-1]->replace('{'.$2.'}')/geo; + # Replace positive replacement strings with arg[$1-1] + # Replace negative replacement strings with arg[$n+$1] + $w =~ s/$pos_inner_regexp/$argset->[$1 > 0 ? $1-1 : $n+$1]->replace('{'.$2.'}')/geo; CORE::push @pos_replacements, $w; } } diff --git a/testsuite/tests-to-run/parallel-local164.sh b/testsuite/tests-to-run/parallel-local164.sh index c0ca7b68..997ad026 100644 --- a/testsuite/tests-to-run/parallel-local164.sh +++ b/testsuite/tests-to-run/parallel-local164.sh @@ -1,10 +1,7 @@ #!/bin/bash -SERVER1=parallel-server3 -SERVER2=parallel-server2 - # -L1 will join lines ending in ' ' -cat <<'EOF' | sed -e s/\$SERVER1/$SERVER1/\;s/\$SERVER2/$SERVER2/ | parallel -j10 -k -L1 +cat <<'EOF' | parallel -j10 -k -L1 echo "### Test --delay" seq 9 | /usr/bin/time -f %e parallel -j3 --delay 0.57 true {} 2>&1 | perl -ne '$_ > 5 and print "More than 5 secs: OK\n"' @@ -115,7 +112,7 @@ echo '### -k -0 -i repl' echo '### test --sshdelay' stdout /usr/bin/time -f %e parallel -j0 --sshdelay 0.5 -S localhost true ::: 1 2 3 | perl -ne 'print($_ > 1.80 ? "OK\n" : "Not OK\n")' -echo 'bug #38299: --resume-failed -k' +echo '### bug #38299: --resume-failed -k' rm /tmp/joblog-38299 parallel -k --resume-failed --joblog /tmp/joblog-38299 echo job{#}id{}\;exit {} ::: 0 1 2 3 0 1 echo try 2 @@ -123,12 +120,17 @@ echo 'bug #38299: --resume-failed -k' echo with exit 0 parallel -k --resume-failed --joblog /tmp/joblog-38299 echo job{#}id{}\;exit 0 ::: 0 1 2 3 0 1 -echo '--resume -k' - rm /tmp/joblog-resume +echo '### --resume -k' + rm -f /tmp/joblog-resume parallel -k --resume --joblog /tmp/joblog-resume echo job{}id\;exit {} ::: 0 1 2 3 0 5 echo try 2 = nothing parallel -k --resume --joblog /tmp/joblog-resume echo job{}id\;exit {} ::: 0 1 2 3 0 5 echo two extra parallel -k --resume --joblog /tmp/joblog-resume echo job{}id\;exit 0 ::: 0 1 2 3 0 5 6 7 +echo '### Negative replacement strings' + parallel -N 6 echo {-1}orrec{1} ::: t B C D E c + parallel -N 6 echo {-1}orrect ::: A B C D E c + + EOF