parallel: Fixed perl expressions spanning multiple lines.

This commit is contained in:
Ole Tange 2018-07-18 14:36:04 +02:00
parent e1e8693797
commit fe92398309
4 changed files with 38 additions and 21 deletions

View file

@ -10001,7 +10001,7 @@ sub replaced {
while($tt =~ s/([^\s\257]* # before {=
(?:
\257< # {=
(?: (?! \257[<>]). )* # The perl expression
(?: [^\257]*|[\257][^<>] )* # The perl expression
\257> # =}
[^\s\257]* # after =}
)+)/ /xs) {
@ -10009,7 +10009,10 @@ sub replaced {
$word{"$1"} ||= 1;
}
} else {
while($tt =~ s/( \257<(?: (?! \257[<>]). )*\257> )//xs) {
while($tt =~ s/( \257<(?: # {=
[^\257]*|[\257][^<>] )* # not \257< or \257>
\257> ) # =}
//xs) {
# $1 = \257< perlexpr \257>
$word{$1} ||= 1;
}
@ -10148,10 +10151,9 @@ sub new {
my $transfer_files = shift;
my $return_files = shift;
my @unget = ();
my ($count,$posrpl,$perlexpr);
my $posrpl;
my ($replacecount_ref, $len_ref);
my @command = @$commandref;
my $dummy = '';
my $seq = 1;
# Replace replacement strings with {= perl expr =}
# '{=' 'perlexpr' '=}' => '{= perlexpr =}'
@ -10180,7 +10182,7 @@ sub new {
# needed to force matching the shortest {= =}
((?:(?! \Q$Global::parensleft\E|\Q$Global::parensright\E ).)*?)
\Q$Global::parensright\E ] # Match =}
{\257<$1\257>}gx;
{\257<$1\257>}gxs;
for my $rpl (sort { length $b <=> length $a } keys %Global::rpl) {
# Replace long --rpl's before short ones, as a short may be a
# substring of a long:
@ -10202,7 +10204,7 @@ sub new {
/xs;
$grp_regexp ||= '';
my $rplval = $Global::rpl{$rpl};
while(s{( (?: ^|\257> ) (?: (?! \257[<>])(?:.|\n) )*? )
while(s{( (?: ^|\257> ) (?: [^\257]*|[\257][^<>] )*? )
# Don't replace after \257 unless \257>
\Q$prefix\E $grp_regexp \Q$postfix\E}
{
@ -10235,7 +10237,7 @@ sub new {
# Only do this if the shorthand start with {
$prefix=~s/^\{//;
# Don't replace after \257 unless \257>
while(s{( (?: ^|\257> ) (?: (?! \257[<>]). )*? )
while(s{( (?: ^|\257> ) (?: [^\257]*|[\257][^<>] )*? )
\{(-?\d+) \s* \Q$prefix\E $grp_regexp \Q$postfix\E}
{
# The start remains the same
@ -10314,13 +10316,13 @@ sub merge_rpl_parts {
my $s = shift @in;
$_ = $s;
# Remove matching (right most) parens
while(s/(.*)$l.*?$r/$1/o) {}
while(s/(.*)$l.*?$r/$1/os) {}
if(/$l/o) {
# Missing right parens
while(@in) {
$s .= " ".shift @in;
$_ = $s;
while(s/(.*)$l.*?$r/$1/o) {}
while(s/(.*)$l.*?$r/$1/os) {}
if(not /$l/o) {
last;
}
@ -10355,7 +10357,7 @@ sub replacement_counts_and_lengths {
my $noncontextlen = 0;
my $contextgroups = 0;
for my $c (@cmd) {
while($c =~ s/ \257<( (?: (?! \257[<>]). )*?)\257> /\000/xs) {
while($c =~ s/ \257<( (?: [^\257]*|[\257][^<>] )*?)\257> /\000/xs) {
# %replacecount = { "perlexpr" => number of times seen }
# e.g { "s/a/b/" => 2 }
$replacecount{$1}++;
@ -10378,7 +10380,7 @@ sub replacement_counts_and_lengths {
# Options that can contain replacement strings
$_ or next;
my $t = $_;
while($t =~ s/ \257<( (?: (?! \257[<>]). )* )\257> //xs) {
while($t =~ s/ \257<( (?: [^\257]*|[\257][^<>] )* )\257> //xs) {
# %replacecount = { "perlexpr" => number of times seen }
# e.g { "$_++" => 2 }
# But for tagstring we just need to mark it as seen

View file

@ -2702,7 +2702,8 @@ To compress all html files using B<gzip> run:
If the file names may contain a newline use B<-0>. Substitute FOO BAR with
FUBAR in all files in this dir and subdirs:
find . -type f -print0 | parallel -q0 perl -i -pe 's/FOO BAR/FUBAR/g'
find . -type f -print0 | \
parallel -q0 perl -i -pe 's/FOO BAR/FUBAR/g'
Note B<-q> is needed because of the space in 'FOO BAR'.
@ -2777,7 +2778,8 @@ in a directory:
To do it recursively use B<find>:
find . -name '*.jpg' | parallel convert -geometry 120 {} {}_thumb.jpg
find . -name '*.jpg' | \
parallel convert -geometry 120 {} {}_thumb.jpg
Notice how the argument has to start with B<{}> as B<{}> will include path
(e.g. running B<convert -geometry 120 ./foo/bar.jpg
@ -2787,7 +2789,8 @@ generate files like ./foo/bar.jpg_thumb.jpg.
Use B<{.}> to avoid the extra .jpg in the file name. This command will
make files like ./foo/bar_thumb.jpg:
find . -name '*.jpg' | parallel convert -geometry 120 {} {.}_thumb.jpg
find . -name '*.jpg' | \
parallel convert -geometry 120 {} {.}_thumb.jpg
=head1 EXAMPLE: Substitution and redirection
@ -3037,16 +3040,15 @@ downloads 10 videos in parallel.
export url
youtube-dl --flat-playlist "$url" |
parallel --tagstring {#} --lb -j10 \
LC_ALL= youtube-dl --playlist-start {#} --playlist-end {#} '"$url"'
youtube-dl --playlist-start {#} --playlist-end {#} '"$url"'
=head1 EXAMPLE: Copy files as last modified date (ISO8601) with added
random digits
=head1 EXAMPLE: Prepend last modified date (ISO8601) to file name
find . | parallel cp {} '../destdir/{= $a=int(10000*rand); $_=pQ($_);
$_=`date -r "$_" +%FT%T"$a"`; chomp; =}'
parallel mv {} '{= $a=pQ($_); $b=$_;' \
'$_=qx{date -r "$a" +%FT%T}; chomp; $_="$_ $b" =}' ::: *
B<{=> and B<=}> mark a perl expression. B<pQ> quotes the
B<{=> and B<=}> mark a perl expression. B<pQ> perl-quotes the
string. B<date +%FT%T> is the date in ISO8601 with time.
@ -3269,7 +3271,8 @@ repeat the list and use replacement string with a Perl expression that
skips the job if the value from input source 1 is greater than or
equal to the value from input source 2:
parallel echo {= 'if($arg[1] ge $arg[2]) { skip() }' =} ::: A B C D ::: A B C D
parallel echo {= 'if($arg[1] ge $arg[2]) { skip() }' =} \
::: A B C D ::: A B C D
Or more generally:

View file

@ -825,6 +825,17 @@ par_pipe_recend() {
seq 3 | parallel -k --pipe --recend '' -n 1 xxd
}
par_perlexpr_with_newline() {
echo 'Perl expression spanning 2 lines'
cd tmp
touch "Dad's \"famous\" 1' pizza"
# Important with newline in perl expression:
parallel mv {} '{= $a=pQ($_); $b=$_;
$_=qx{date -r "$a" +%FT%T}; chomp; $_="$_ $b" =}' \
::: "Dad's \"famous\" 1' pizza"
rm *"Dad's \"famous\" 1' pizza"
}
export -f $(compgen -A function | grep par_)
compgen -A function | grep par_ | sort |
parallel -j6 --tag -k --joblog +/tmp/jl-`basename $0` '{} 2>&1'

View file

@ -1386,6 +1386,7 @@ par_parcat_args_stdin OK2
par_parcat_rm bug #51691: parcat --rm remove fifo when opened
par_parcat_rm OK1
par_parcat_rm OK file removed
par_perlexpr_with_newline Perl expression spanning 2 lines
par_pipe_no_command ### --pipe without command
par_pipe_no_command parallel: Error: --pipe/--pipepart must have a command to pipe into (e.g. 'cat').
par_pipe_recend bug #54328: --pipe --recend blocks