luissquall
luissquall

Reputation: 1880

Construct perl command params from the command line

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

Upvotes: 0

Views: 84

Answers (3)

konsolebox
konsolebox

Reputation: 75588

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" " ")"

Upvotes: 1

Etan Reisner
Etan Reisner

Reputation: 81052

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.

Upvotes: 0

Mr. Llama
Mr. Llama

Reputation: 20919

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 .....)

Upvotes: 0

Related Questions