I am trying to call an executable with two arguments within a nested for loop (I'm also writing in bash scripting). I thought I was doing it correctly, but all my values show up in the text file as 0. i.e. tilt 0 angle 0 even though the values are obviously not. My code is as such:
for (( i=0; i <=3; i++)); do
for (( j=0; j <= 3; j++ )); do
./solar_sim 'i' 'j' >> solarResults.txt
echo -n "$i"
done
echo " "
done
`
The solar_sim was provided to us and output a line like this, which I write to a file:
10000 hours, angle: 0.00 degrees, temperature: 0.00 degrees C, total power: 119871.00 Watts
Am I doing something wrong in the calling of solar_sim? I also tried using $i and $j
Your mistake is this line :
./solar_sim 'i' 'j' >> solarResults.txt
should be rewritten like this :
./solar_sim "$i" "$j" >> solarResults.txt
Also, echo is sufficient alone, no need echo " " to print a newline
It looks like you forgot the "$" to de-reference the i and j variables
./solar_sim "$i" "$j" >> solarResults.txt
Related
I am trying to write bash script that get 3 arguments of paths.
for ex /tmp/1 /tmp/2 /tmpnew
I want to iterate over the argument except the last one and each time copy the file to the path of the last argument.
I have problem with echo '${files[$(($len))]}' inside the for. I cant pull the last argument like that.
files=( "$#" )
len=${#files[#]}
echo $len
for (( i=0; i<$(( $len -1 )); i++ ))
do
echo ${files[$(($len))]}
echo ${files[$i]}
done
The last element is ${files[len-1]}, or simply ${files[-1]}.
Similarly, you can use just ${files[i]}. If the array is not associative, bash interprets the index as an arithmetic expression.
#!/bin/bash
files=("$#")
len=${#files[#]}
echo $len
for (( i=0; i<len-1; i++ )) ; do
echo "${files[-1]}"
echo "${files[i]}"
done
I have an issue with some homework, so basically we were asked to create a bash script that takes a variable greater than 2 and gives back the same number of Fibonacci sequence numbers, i.o. if i were to give 5 it would print:
0 1 1 2 3
I have done some research and have come up with a unique idea i havent really seen anywhere online, (keep in mind i have some experience in python) but i have run into a problem, so basically i use a for expression in bash and 2 variables to calculate the sequence, i first manually set them to be 0 and 1 (the first and second numbers in the sequence) and then i add them together while changing their values,
So here is the code :
#!/bin/bash
a=0
b=1
for i in $(seq 1 $1);
do
if ["$a" -gt "$b"]
then
b=($a +$b)
echo "$b"
else
a=($a +$b)
echo $a
fi
done
I have many issues and expect to be completely out of context but i hope you get the general idea and can help guide me through the problem :/
It seems like i want something to be treated as a number but its treated as text... Not sure though, any help is highly appreciated
You were very close, some small syntactic changes and new initial values make it work.
Notes:
whitespace is important in bash, especially with special characters [ ] ;
also, calculation with integer number can be forced using let
Nice idea to use a comparison to do the calculation with just two variables :)
#!/bin/bash -
a=1
b=0
echo $a
for i in $(seq 1 $1);
do
if [ $a -gt $b ] ; then
let b=($a +$b)
echo $b
else
let a=($a +$b)
echo $a
fi
done
there is an arithmetic context in bash.
slight re-write can be
$ a=0; b=1;
for i in {1..9};
do c=$((a+b));
echo $c;
if ((a>b)); then b=$c; else a=$c; fi;
done
1
2
3
5
8
13
21
34
55
You need a space
if [ "$a" -gt "$b" ]
and you can do arithmetic evaluation using
b=$((a+b))
once the script runs, verify the result is what you are expecting (i.e. does it print 0?)
Use double parens to evaluate arithmetic expressions. Instead of:
if [ "$a" -gt "$b" ]
write:
if ((a > b))
and instead of:
($a + $b)
write:
$((a + b))
You can also write the for header this way:
for ((i = 0; i < $1; i++))
But this is not required in this case. Your loop then becomes:
for ((i = 0; i < $1; i++)); do
if ((a > b)); then
b=$((a + b))
echo "$b"
else
a=$((a + b))
echo "$a"
fi
done
#!/bin/bash
a=0
b=1
echo $a
c=$1
for i in $(seq 1 $((c-1)));
do
if [ $a -gt $b ]; then
b=$((a+b))
echo $b
else
a=$((a+b))
echo $a
fi
done
My script:
for (( i=1; i <= $j; i++ ))
do
list_$i = $i
echo "$list_$i"
done
Expected output:
1
2
3
.
.
.
etc
I have a problem with the echo statement while calling the variable.
Please help me on this.
Assuming that $j has an nonnegative integral value,
for (( i=1; $i<=$j; i=$i+1 ))
do
list[$i]=$i
echo "${list[$i]}"
done
Bash arrays are used, whereby $list is a single structure, a Bash array.
First remember that a variable assignment is without spaces around the =.
What you are trying to do, is possible but complicated.
for (( i=1; i <= 6; i++ )); do
source <(echo "list_$i=$i")
varname=list_$i
echo "${!varname}"
done
You can also view the results in a different loop
for result in list_{1..6}; do
echo "${result}=${!result}"
done
I have a few text files with numbers (structure as below). I'd like to sum up every line form one file with ever line form other files (line1 from file1 + line1 from file2 etc.). I have written the bash script as following but this gives me the expr error.
function countHourly () {
for i in {1..24}
do
for file in $PLACE/*.dailycount.txt
do
SECBUFF=`head -n $i $file`
VAL=`expr $VAL + $SECBUFF` ## <-- this cause expr error
done
echo line $i form all files counts: $VAL
done
}
file structure *.dailycount.txt:
1
0
14
56
45
0
3
45
23
23
9 (every number in new line).
Assuming your files each contain exactly 24 lines, you could solve this problem with a simple one-liner:
counthourly() {
paste -d+ $PLACE/*.dailycount.txt | bc
}
The head -n NUMBER FILE command outputs the first NUMBER lines. This means that SECBUFF ends up being 1 0 on the second run of the loop, and something like expr 1 + 2 3 is not a valid expression so you get an error from expr.
You can use sed to pick only the nth line from a file, but I wonder if you shouldn't restructure the program somehow.
SECBUFF=`sed -ne ${i}p $file`
This could help. With that variation you could check very input so that only numbers would be added for the sum, even if there are lines that invalid.
function countHourly {
local NUMBERS TOTAL=0 I
readarray -t NUMBERS < <(cat "$PLACE"/*.dailycount.txt)
for I in "${NUMBERS[#]}"; do
[[ $I =~ ^[[:digit:]]+$ ]] && (( TOTAL += I ))
done
echo "Total: $TOTAL"
}
Or
function countHourly {
local NUMBERS TOTAL=0 I
while read I; do
[[ $I =~ ^[[:digit:]]+$ ]] && (( TOTAL += I ))
done < <(cat "$PLACE"/*.dailycount.txt)
echo "Total: $TOTAL"
}
Bubble Sort : (Original Code)
clear
echo "Enter size : "
read size
echo "Enter elements : "
for (( i=0; i<size; i++ ))
do
echo "Element " $i " : "
read arr[$i]
done
m=$(($n-1))
for (( i=0; i<m; i++ ))
do
cond=$((size-$i-1))
for (( j=0; j<cond; j++ ))
do
l=$(($j+1));
if [ ${a[$j]} -gt ${a[$l]} ]
then
tmp=${a[$j]}
a[$j]=${a[$l]}
a[$l]=$tmp
fi
done
done
echo "Sorted Data : "
echo ${a[*]}
This code is executing, while it takes the input and stores them in the array.
The the next thing I see is, "Sorted Array" being printed.
and no elements are printed after that.
Tried, sh -x sort.sh and the interim code isn't being executed.
I am quite new to shell script and cannot understand what's wrong.
Bubble Sort : (Corrected Code)
clear
echo "Enter size : "
read size
echo "Enter elements : "
for (( i=0; i<size; i++ ))
do
echo "Element " $i " : "
read arr[$i]
done
m=$(($size-1))
for (( i=0; i<m; i++ ))
do
cond=$(($size-$i-1))
for (( j=0; j<cond; j++ ))
do
l=$(($j+1));
if [ ${arr[$j]} -gt ${arr[$l]} ]
then
tmp=${arr[$j]}
arr[$j]=${arr[$l]}
arr[$l]=$tmp
fi
done
done
echo "Sorted Data : "
echo ${arr[*]}
Two things that are wrong in your program:
Line No. 8 - You are calling your array arr[] but later referring it as a[] . Change one of the names to match the other.
Line No. 10 - There is no $n in your program. You mean $size. Change this as well.
I think your program should work after this.
Problem 1: You've used $size and $n interchangeably.
Problem 2: You've again used the arr[] and a[] arrays interchangeably.