mirror of
https://git.savannah.gnu.org/git/parallel.git
synced 2024-11-22 14:07:55 +00:00
parallel: Fixed perl expressions spanning multiple lines.
This commit is contained in:
parent
e1e8693797
commit
fe92398309
24
src/parallel
24
src/parallel
|
@ -10001,7 +10001,7 @@ sub replaced {
|
||||||
while($tt =~ s/([^\s\257]* # before {=
|
while($tt =~ s/([^\s\257]* # before {=
|
||||||
(?:
|
(?:
|
||||||
\257< # {=
|
\257< # {=
|
||||||
(?: (?! \257[<>]). )* # The perl expression
|
(?: [^\257]*|[\257][^<>] )* # The perl expression
|
||||||
\257> # =}
|
\257> # =}
|
||||||
[^\s\257]* # after =}
|
[^\s\257]* # after =}
|
||||||
)+)/ /xs) {
|
)+)/ /xs) {
|
||||||
|
@ -10009,7 +10009,10 @@ sub replaced {
|
||||||
$word{"$1"} ||= 1;
|
$word{"$1"} ||= 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while($tt =~ s/( \257<(?: (?! \257[<>]). )*\257> )//xs) {
|
while($tt =~ s/( \257<(?: # {=
|
||||||
|
[^\257]*|[\257][^<>] )* # not \257< or \257>
|
||||||
|
\257> ) # =}
|
||||||
|
//xs) {
|
||||||
# $1 = \257< perlexpr \257>
|
# $1 = \257< perlexpr \257>
|
||||||
$word{$1} ||= 1;
|
$word{$1} ||= 1;
|
||||||
}
|
}
|
||||||
|
@ -10148,10 +10151,9 @@ sub new {
|
||||||
my $transfer_files = shift;
|
my $transfer_files = shift;
|
||||||
my $return_files = shift;
|
my $return_files = shift;
|
||||||
my @unget = ();
|
my @unget = ();
|
||||||
my ($count,$posrpl,$perlexpr);
|
my $posrpl;
|
||||||
my ($replacecount_ref, $len_ref);
|
my ($replacecount_ref, $len_ref);
|
||||||
my @command = @$commandref;
|
my @command = @$commandref;
|
||||||
my $dummy = '';
|
|
||||||
my $seq = 1;
|
my $seq = 1;
|
||||||
# Replace replacement strings with {= perl expr =}
|
# Replace replacement strings with {= perl expr =}
|
||||||
# '{=' 'perlexpr' '=}' => '{= perlexpr =}'
|
# '{=' 'perlexpr' '=}' => '{= perlexpr =}'
|
||||||
|
@ -10180,7 +10182,7 @@ sub new {
|
||||||
# needed to force matching the shortest {= =}
|
# needed to force matching the shortest {= =}
|
||||||
((?:(?! \Q$Global::parensleft\E|\Q$Global::parensright\E ).)*?)
|
((?:(?! \Q$Global::parensleft\E|\Q$Global::parensright\E ).)*?)
|
||||||
\Q$Global::parensright\E ] # Match =}
|
\Q$Global::parensright\E ] # Match =}
|
||||||
{\257<$1\257>}gx;
|
{\257<$1\257>}gxs;
|
||||||
for my $rpl (sort { length $b <=> length $a } keys %Global::rpl) {
|
for my $rpl (sort { length $b <=> length $a } keys %Global::rpl) {
|
||||||
# Replace long --rpl's before short ones, as a short may be a
|
# Replace long --rpl's before short ones, as a short may be a
|
||||||
# substring of a long:
|
# substring of a long:
|
||||||
|
@ -10202,7 +10204,7 @@ sub new {
|
||||||
/xs;
|
/xs;
|
||||||
$grp_regexp ||= '';
|
$grp_regexp ||= '';
|
||||||
my $rplval = $Global::rpl{$rpl};
|
my $rplval = $Global::rpl{$rpl};
|
||||||
while(s{( (?: ^|\257> ) (?: (?! \257[<>])(?:.|\n) )*? )
|
while(s{( (?: ^|\257> ) (?: [^\257]*|[\257][^<>] )*? )
|
||||||
# Don't replace after \257 unless \257>
|
# Don't replace after \257 unless \257>
|
||||||
\Q$prefix\E $grp_regexp \Q$postfix\E}
|
\Q$prefix\E $grp_regexp \Q$postfix\E}
|
||||||
{
|
{
|
||||||
|
@ -10235,7 +10237,7 @@ sub new {
|
||||||
# Only do this if the shorthand start with {
|
# Only do this if the shorthand start with {
|
||||||
$prefix=~s/^\{//;
|
$prefix=~s/^\{//;
|
||||||
# Don't replace after \257 unless \257>
|
# 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}
|
\{(-?\d+) \s* \Q$prefix\E $grp_regexp \Q$postfix\E}
|
||||||
{
|
{
|
||||||
# The start remains the same
|
# The start remains the same
|
||||||
|
@ -10314,13 +10316,13 @@ sub merge_rpl_parts {
|
||||||
my $s = shift @in;
|
my $s = shift @in;
|
||||||
$_ = $s;
|
$_ = $s;
|
||||||
# Remove matching (right most) parens
|
# Remove matching (right most) parens
|
||||||
while(s/(.*)$l.*?$r/$1/o) {}
|
while(s/(.*)$l.*?$r/$1/os) {}
|
||||||
if(/$l/o) {
|
if(/$l/o) {
|
||||||
# Missing right parens
|
# Missing right parens
|
||||||
while(@in) {
|
while(@in) {
|
||||||
$s .= " ".shift @in;
|
$s .= " ".shift @in;
|
||||||
$_ = $s;
|
$_ = $s;
|
||||||
while(s/(.*)$l.*?$r/$1/o) {}
|
while(s/(.*)$l.*?$r/$1/os) {}
|
||||||
if(not /$l/o) {
|
if(not /$l/o) {
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
@ -10355,7 +10357,7 @@ sub replacement_counts_and_lengths {
|
||||||
my $noncontextlen = 0;
|
my $noncontextlen = 0;
|
||||||
my $contextgroups = 0;
|
my $contextgroups = 0;
|
||||||
for my $c (@cmd) {
|
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 }
|
# %replacecount = { "perlexpr" => number of times seen }
|
||||||
# e.g { "s/a/b/" => 2 }
|
# e.g { "s/a/b/" => 2 }
|
||||||
$replacecount{$1}++;
|
$replacecount{$1}++;
|
||||||
|
@ -10378,7 +10380,7 @@ sub replacement_counts_and_lengths {
|
||||||
# Options that can contain replacement strings
|
# Options that can contain replacement strings
|
||||||
$_ or next;
|
$_ or next;
|
||||||
my $t = $_;
|
my $t = $_;
|
||||||
while($t =~ s/ \257<( (?: (?! \257[<>]). )* )\257> //xs) {
|
while($t =~ s/ \257<( (?: [^\257]*|[\257][^<>] )* )\257> //xs) {
|
||||||
# %replacecount = { "perlexpr" => number of times seen }
|
# %replacecount = { "perlexpr" => number of times seen }
|
||||||
# e.g { "$_++" => 2 }
|
# e.g { "$_++" => 2 }
|
||||||
# But for tagstring we just need to mark it as seen
|
# But for tagstring we just need to mark it as seen
|
||||||
|
|
|
@ -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
|
If the file names may contain a newline use B<-0>. Substitute FOO BAR with
|
||||||
FUBAR in all files in this dir and subdirs:
|
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'.
|
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>:
|
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
|
Notice how the argument has to start with B<{}> as B<{}> will include path
|
||||||
(e.g. running B<convert -geometry 120 ./foo/bar.jpg
|
(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
|
Use B<{.}> to avoid the extra .jpg in the file name. This command will
|
||||||
make files like ./foo/bar_thumb.jpg:
|
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
|
=head1 EXAMPLE: Substitution and redirection
|
||||||
|
@ -3037,16 +3040,15 @@ downloads 10 videos in parallel.
|
||||||
export url
|
export url
|
||||||
youtube-dl --flat-playlist "$url" |
|
youtube-dl --flat-playlist "$url" |
|
||||||
parallel --tagstring {#} --lb -j10 \
|
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
|
=head1 EXAMPLE: Prepend last modified date (ISO8601) to file name
|
||||||
random digits
|
|
||||||
|
|
||||||
find . | parallel cp {} '../destdir/{= $a=int(10000*rand); $_=pQ($_);
|
parallel mv {} '{= $a=pQ($_); $b=$_;' \
|
||||||
$_=`date -r "$_" +%FT%T"$a"`; chomp; =}'
|
'$_=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.
|
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
|
skips the job if the value from input source 1 is greater than or
|
||||||
equal to the value from input source 2:
|
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:
|
Or more generally:
|
||||||
|
|
||||||
|
|
|
@ -825,6 +825,17 @@ par_pipe_recend() {
|
||||||
seq 3 | parallel -k --pipe --recend '' -n 1 xxd
|
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_)
|
export -f $(compgen -A function | grep par_)
|
||||||
compgen -A function | grep par_ | sort |
|
compgen -A function | grep par_ | sort |
|
||||||
parallel -j6 --tag -k --joblog +/tmp/jl-`basename $0` '{} 2>&1'
|
parallel -j6 --tag -k --joblog +/tmp/jl-`basename $0` '{} 2>&1'
|
||||||
|
|
|
@ -1386,6 +1386,7 @@ par_parcat_args_stdin OK2
|
||||||
par_parcat_rm bug #51691: parcat --rm remove fifo when opened
|
par_parcat_rm bug #51691: parcat --rm remove fifo when opened
|
||||||
par_parcat_rm OK1
|
par_parcat_rm OK1
|
||||||
par_parcat_rm OK file removed
|
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 ### --pipe without command
|
||||||
par_pipe_no_command parallel: Error: --pipe/--pipepart must have a command to pipe into (e.g. 'cat').
|
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
|
par_pipe_recend bug #54328: --pipe --recend blocks
|
||||||
|
|
Loading…
Reference in a new issue