0

I would like to add multiple -e command dynamically to perl but it throws multiple errors like this:

String found where operator expected at -e line 2, near "'s/\$testName/\$test-name/g;'" (Missing semicolon on previous line?)

Heres what I'm doing:

find css -name "*.scss" -print0 | \
xargs -0 -t perl -pi \
$(perl -ne '/^(\$(?=[a-z0-9]*[A-Z])[^:\s]+)\s*:/ && print "-e \047s/\\$1/\\" . lc(join("-", split(/(?=[A-Z])/, $1))) . "/g;\047\n"' _variables.scss | sort -ur | tr "\n" " ")

The command $(perl -ne ...) extracts and transforms some content and outputs something like:

-e 's/\$testName/\$test-name/g;' -e 's/\$coolName/\$cool-name/g;' -e 's/\$camelCased/\$camel-cased/g;'

As far as I can tell the problem resides in the way bash/perl evaluates the last command, the manual execution of the command output by "xargs -t" works fine.

The following simple case fails too:

target="-e 's/\$testName/\$test-name/g;' -e 's/\$coolName/\$cool-name/g;' 's/\$camelCased/\$camel-cased/g;'"
perl -pi $target css/core.scss
3
  • Where do you pass the arguments produced by xargs, to the outer perl or the inner one? Commented Aug 4, 2014 at 16:29
  • To the outer perl: "search and replace all pairs provided by the inner perl". Commented Aug 4, 2014 at 16:59
  • You don't get quote removal on the results of variable expansion and command substituion. See mywiki.wooledge.org/BashFAQ/050 . Commented Aug 4, 2014 at 17:00

3 Answers 3

1

Try this:

ARGS=$(perl -ne '/^(\$(?=[a-z0-9]*[A-Z])[^:\s]+)\s*:/ && print "-e \047s/\\$1/\\" . lc(join("-", split(/(?=[A-Z])/, $1))) . "/g;\047\n"' _variables.scss | sort -ur | tr "\n" " ")
eval "find css -name '*.scss' -print0 | xargs -0 -t perl -pi $ARGS"

Or

eval "find css -name '*.scss' -print0 | xargs -0 -t perl -pi $(perl -ne '/^(\$(?=[a-z0-9]*[A-Z])[^:\s]+)\s*:/ && print "-e \047s/\\$1/\\" . lc(join("-", split(/(?=[A-Z])/, $1))) . "/g;\047\n"' _variables.scss | sort -ur | tr "\n" " ")"
Sign up to request clarification or add additional context in comments.

1 Comment

It works great, is it possible to make it work without the ARGS var? Something similar to @mr-llama suggestion: "find ... | xargs -0 -t eval..."?
0

You'll need to include an eval with the xargs to get the variable to be parsed as parameters. Here's a quick demonstration:

# Variable containing parameters
> target="-e 's/a/b/g;' -e 's/x/y/g;'"

# Variable substitution - Doesn't work
> echo "aaaabbbbccccddddxxxx" | perl -pi ${target}
String found where operator expected at -e line 2, near "'s/x/y/g;'"
        (Missing semicolon on previous line?)
syntax error at -e line 2, near "'s/x/y/g;'"
Execution of -e aborted due to compilation errors.

# Manual substitution - Works
> echo "aaaabbbbccccddddxxxx" | perl -pi -e 's/a/b/g;' -e 's/x/y/g;'
bbbbbbbbccccddddyyyy

# Eval substitution - Works
> echo "aaaabbbbccccddddxxxx" | eval perl -pi ${target}
bbbbbbbbccccddddyyyy

In your situation, the following should work:

find css -name "*.scss" -print0 | \
    xargs -0 -t eval perl -pi $(perl -ne .....)

1 Comment

Thank you @Mr. Llama. I couldn't make it work with eval and xargs. I got this error: "xargs: eval: No such file or directory".
0

You don't get quote removal on the results of variable expansion and command substituion.

See http://mywiki.wooledge.org/BashFAQ/050 for more details.

You can't get what you want here the way you are trying to do it. Store the results of the inner perl in an array and expand that on the outer perl command.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.