3

I am writing a shell script to replace a variable content which is an integer with another, using perl in a shell script.

#!/bin/sh

InitialFileStep="$1"
CurrentStage=$((($i*(9*4000))+$InitialFileStep))
PreviousStage=$((($(($(($i-1))*(9*4000)))) + (InitialFileStep)))

perl -pi -e 's/$PreviousStage/$CurrentStage/g' file.txt
echo "Hey!"

It seems it cannot find the variable content in the file. I don't know what is the problem, is it the because the variables are integers and not strings?

4
  • 2
    Wrong quotes in perl call? Commented Oct 11, 2015 at 2:07
  • Yeah, that defines shell variables but uses (undefined) Perl variables. Commented Oct 11, 2015 at 2:16
  • Your code has another problem: test.sh: line 4: (*(9*4000))+42: syntax error: operand expected (error token is "*(9*4000))+foo"). Where does $i come from? Commented Oct 11, 2015 at 3:48
  • You are right, 'i' shouldn't be there as well. Commented Oct 12, 2015 at 1:39

2 Answers 2

2

The shell does not interpret anything inside single quote. '$ThisIsASimpleStringForTheShell' so try:

perl -pi -e 's/'"$PreviousStage"'/'"$CurrentStage"'/g' file.txt

The double quotes prevents possible spaces to mess up your command.

Mixing single and double quotes gives you the possibility to add regex operator to your command, preventing shell to interpret them before perl. This command substitute the contents of $PreviousStage with the contents of $CurrentStage only if the former is alone in a single line:

perl -pi -e 's/^'"$PreviousStage"'$/'"$CurrentStage"'/g' file.txt
Sign up to request clarification or add additional context in comments.

3 Comments

@ikegami: i've used sed in the answer (mixing it with variables shell in the standard way this is done). No mix between separate races is made so you can now recover a point :)
Same issues with generating sed code as with generating Perl code. By switching to sed, you lost the ability to use \Q, so you've actually taken a step back. But since the scope is just integers, this is all moot, and I'll remove my downvote, comment, and the edit you made because of my comment. (Feel free to switch it back to sed if that's really what you want)
@ikegami: i generally agree with you, also thank you for make me discover \Q. (cool you can edit every post :)
2

The variables only exist in your shell script; you can't directly use them in your Perl script.

I hate attempting to generate Perl code from the shell as the previous solutions suggest. That way madness lies (though it works here since you're just dealing with integers). Instead, pass the values as arguments or some other way.

perl -i -pe'BEGIN { $S = shift; $R = shift; } s/\Q$S/$R/g' \
   "$PreviousStage" "$CurrentStage" file.txt

or

export PreviousStage
export CurrentStage
perl -i -pe's/\Q$ENV{PreviousStage}/$ENV{CurrentStage}/g' file.txt

or

S="$PreviousStage" R="$CurrentStage" perl -i -pe's/\Q$ENV{S}/$ENV{R}/g' file.txt

1 Comment

Might as well dio the math in perl too

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.