Linux Shell-Script code is not executing as it should - linux

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.

Related

How to write script for arithmetic mean of even numbers

I have to write a script in bash where I have to provide 10 numbers to the table. Then script have to write the content out and arithmetic mean of even numbers. I did like 90% of the script, but I can't find out how to extract information about quantity of even numbers that is needed for arithmetic mean.
Here is my code:
echo "Provide data:"
i=0
for (( i = 0 ; i < 10; i++ ))
do
echo "Provide $[$i+1] number:"
read x
if [ "$x" = "" ]
then
break
else
table[$i]=$x
fi
done
echo "Provided data: ${table[*]}"
result=0
for (( i = 0 ; i < 10; i++))
do
res=$[${table[i]}%2]
if [ $res -eq 0 ]
then
echo "Number ${table[i]} is even"
result=$[$result+${table[$i]}]
fi
done
echo "SUM:$[$result]"
ignoring data input adding only odd inputs can look like :
$ cat c.sh
#!/bin/bash
declare -A xDarray
sum=0
xDarray[0 1]=1
xDarray[0 2]=3
xDarray[1 0]=2
xDarray[2 0]=4
for var in ${xDarray[#]}
do
if [ $(( $var & 1 )) == 0 ] ; then
echo $var is even
i+=1
tab[$i]=$var
sum=$(( $sum + $var))
fi
done
var=$(echo ${tab[#]} | sed 's/ / + /g' )
echo $var = $sum
result in
$ ./c.sh
2 is even
4 is even
2 + 4 = 6
$
whatever the number of data is used it would work
I let you work around your data input
Here are some suggested modifications for your script, syntax is simple.
#!/bin/bash
arr=()
for (( i=1;i<=10;i++ )); do
number=''
while [[ ! $number =~ ^[0-9]+$ ]]; do
printf "Please enter number $i:\n"
read number
done
arr+=($number)
done
printf "\nProvided numbers:"
printf " %d" "${arr[#]}"
printf "\nEven numbers:"
s=0
n=0
for x in "${arr[#]}"; do
if ! (( x % 2 )); then
printf " %d" "$x"
s=$(( s + x ))
(( n++ ))
fi
done
m=$(( s / n ))
printf "\nMean of the %d even numbers: %d / %d = %d\n" "$n" "$s" "$n" "$m"
Use an array arr to hold the input numbers, declare with arr=(), append numbers with arr+=($x), we refer only ${arr[#]} for all the items and we avoid any other complex array references, indices etc.
Every input number is tested against regular expression ^[0-9]+$ which means one or more digits (and only digits) with the =~ operator, and if this is not true, we prompt again for the same i-th input number.
Also we prefer printf for printing.
The last loop is the standard array loop, where we use again the arithmetic expansion syntax to find the even numbers, to add them to the sum and get the mean of them (result is an integer).
If you want to print a decimal result, e.g. with 2 floating points, you could use bc and printf "%f" like this:
m=$( bc <<< "scale=2; $s/$n" )
printf "%.2f" "$m"

How to add called variable as a suffix to another variable and then call the suffixed variable?

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

How do you search an array for a variable using bash's test [ ] built-in?

Using the test built-in to compare my variable to an array fails with error "Syntax error in expression".
I've tried requoting the var_names, using == and -eq, and several old tricks from SO questions from 8+ years ago.
#!/bin/bash
TOTAL=0
declare -a FREQ=(0);
main(){
for i in $(cat "$1");
do
TOTAL=$(( $i + FREQ[-1] ))
echo Total is $TOTAL
if [[ $TOTAL -eq "${FREQ[#]}" ]];
then
echo "Matching Frequency Found: " $TOTAL
exit
else
FREQ=(${FREQ[#]} $TOTAL)
fi
done
return $TOTAL
return $FREQ
}
main $#
I expect $TOTAL to be found in the array of $FREQ when the script is called with ./script.sh input.txt which holds over 1000 integers.
I'm not sure I get what you're trying to do, but try a lookup table.
TOTAL=0
declare -a FREQ=(0)
declare -A lookup=( [0]=1 )
while read -r i
do TOTAL=$(( $i + FREQ[-1] ))
if (( ${lookup[$TOTAL]} ))
then echo "Matching Frequency Found: " $TOTAL
exit
else lookup[$TOTAL]=1
FREQ+=($TOTAL)
fi
done < "$1"
As that logic stands, though, I don't think it will ever hit a found frequency unless some of them are negative...

Calling an executable within a nested for loop in linux

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

Bubble sort in Linux/Unix shell scripting

I am trying to perform bubble sort is Unix shell script. Why is my code not working?
a=(10 8 20 25 12)
for ((i=0;i<5;i++))
do
for((j=0;j<5;j++))
do
if ((${a[j]} > ${a[$((j+1))]}))
then
v=${a[$j]}
a[$j]=${a[$((j+1))]}
a[$((j+1))]=$v
fi
done
done
echo ${a[*]}
echo "end..."
I guess this is homework. therefore I don't give codes, just point out the errors in your codes:
for((j=0;j<5;j++)) then read a[j+1], here would be problem because when j=4, j+1 doesn't exist
fix that, your program will sort.
Try this:
echo "Enter size of array";
read n; #get the size of array from user.
echo "Enter the array";
read -a arr; #get the array form user eg: 2 3 4 5 6
echo "Orignal array is: ${arr[*]}"; #print orignal array
flag=1;
for (( i = 0; i < $n-1; i++ ))
do
flag=0;
for ((j = 0; j < $n-1-$i; j++ ))
do
if [[ ${arr[$j]} -gt ${arr[$j+1]} ]]
then
temp=${arr[$j]};
arr[$j]=${arr[$j+1]};
arr[$j+1]=$temp;
flag=1;
fi
done
if [[ $flag -eq 0 ]]; then
break;
fi
done
echo "Final sorted Array is ${arr[*]}";

Resources