I am trying to increment a counter variable that sits within a seperate text variable. I am initializing the counter variable once only at the start of my code. I expected to be able to increment the counter and have the text variable (that countains the counter) display as incremented throughout my code, only this isn't the case.
For example, using a text file containing the word "hello" as it
s contents. I expected the code below to give me 2 seperate text files like so:
run1.txt "testing1"
run2.txt "testing2"
The issue is, I'm receiving:
run1.txt "testing1"
run2.txt "testing1"
!/bin/bash
run_number=0
((run_number++)) #run_number is now 1
run="testing$run_number" #run is now 'testing1'
echo $run_number #displays 1
cp template.txt run1.txt #make a copy of a file that contains "hello"
sed -i 's#hello#'$run'#g' run1.txt #replace "hello" with var run ("testing1")
cat run1.txt #display new contents of file, "testing1"
echo "--------------------------------------------"
((run_number++)) #increment variable so that now, run_number=2
echo $run_number #displays 2
cp template.txt run2.txt #make copy of file that contains "hello"
sed -i 's#hello#'$run'#g' run2.txt #replace "hello" with "testing2"
cat run2.txt #display "testing2"?? this returns testing1
I am aware that I can simply initialize the variable..
run="testing$run_number" #run is now 'testing1
later on, after incrementing "run_number" but this seems redundant.
I see. Do you know if there is a way to increment a variable within a variable and have it remain throughout? I don't want it to be a one time thing because I plan on incrementing it in a for loop over several iterations.
Not really, no. In Bash, variables are only ever updated at the time something is assigned to them. If other variables that were used to determine their value are themselves updated, this will not change the values of other variables dynamically.
A quick example is probably the easiest way to demonstrate this.
So basically, the contents of a variable will only ever be updated when something is assigned to that variable, regardless of what happens to any other variables that were originally used to determine the contents of the variable in question.
#!/bin/bash
for ((run_number=1; run_number<=2; run_number++))
do
run=testing$run_number
runfile=run${run_number}.txt
cp "template.txt" "$runfile"
echo "$run_number"
sed -i "s#hello#${run}#g" "$runfile" #replace "hello" with var run
cat "$runfile" #display new contents of file
echo "--------------------------------------------"
done
Very true! ;-)) eval is the command which sole purpose is to be avoided, so to say.
In a stricter sense this is also problematic. You need to know in the main program, that the variable in container() is named in a certain way (here "myvar"). You could alleviate this dependency by doing:
This could indeed be an improvement, or not, depending on the context.
If application logic tells us that this variable always MUST be the same (for example, if it is an environment variable with an application-wide well-defined meaning, such as USER or CLASSPATH or OUR_GIT_REPO, I think it is better not to pass it as parameter. Having always the same parameter is annoying to type and invites typing mistakes. If this context is used with different variables often (i.e. our function container works a bit like a "formatter" for values), your approach is better.