how do you make a reverse number pyramid in bash - bash

I'm trying to make a reverse pyramid that outputs
$ ./reverse_pyramid **3**
1 2 3 2 1
1 2 1
1
This is what I have but it outputs nothing and has no syntax errors:
#!/bin/bash
# get input
read -p "Enter number:" num
#outside of pyramid
for((i=1;i>=num;i--))
do
#Loop to print numbers
for((s=i;s>=num;s--))
do
echo -ne "#"
done
#left half
for((j=1;j<=i;j++))
do
echo -ne "$j"
done
#right
for((l=(i-1);l>=1;l--))
do
echo -ne "$l"
done
#add a line
echo
done

It's due to this line:
for((i=1;i>=num;i--))
you're setting i to 1 which is smaller than your input num of 3 so your loop won't execute.
As a side note, I recommend you use -x option when debugging bash programs:
bash -x myprogram.sh
This will show you all the execution steps and pinpoints where it might be going wrong

Related

how to print no. from n to 1 from the pattern in shell script

display the loop
7 6 5 4 3 2 1
5 4 3 2 1
3 2 1
1
how to print this pattern no idea of printing it from n to 1
read -p "Enter rows:" rows
for ((a=$rows;a>=1;a--))
do
for ((b=$rows;b>$a;b--))
do
echo -n " "
done
for ((c=1;c<=$a;c++))
do
echo -n '* '
if [ $c = $a ]
then
echo -e '\n'
fi
done
done
please help to print this pattern loop not have enough spaces if i take n as 7 then printing it in 4 line will be difficult for me
The immediate error is that your requirement calls for subtracting two items from the start in each iteration, but you only subtract one.
More generally, probably avoid echo -e entirely; learn to use printf if you need detailed control over newlines etc.
for ((a=$rows; a>=1; a-=2)); do
printf -v sep "%$((rows - a))s" ""
for ((b=$a; b>=1; b--)); do
printf "%s%i" "$sep" "$b"
sep=" "
done
printf '\n'
done
And, as demonstrated here, probably learn to indent your code to show how blocks are nested.
Tangentially, perhaps better to accept the number of rows as a command-line argument rather than prompt interactively for a value. Interactive I/O is pesky when you want to use your script as part of another larger script.

`echo " $1 % 2" | bc -l` doesn't work in the terminal or bash script but `bc` takes these arguments within `bc` [duplicate]

This question already has answers here:
bash, bc modulo does not work with -l flag
(5 answers)
How do I check whether a variable has an even numeric value?
(3 answers)
Closed 4 years ago.
I haven't been able to find anything related to this nor can my professor explain what's going on. Below is the problem description:
After quite a bit of debugging following is the bash script to print odd or even:
echo $1
odd_even=$(echo "$1 % 2" | bc -l)
echo $odd_even
if [[ $odd_even -eq 0 ]]
then
echo "even"
else
echo "odd"
fi
Following is the output:
$ bash logic_ex2.sh 3
3
0
even
This is weird because the variable odd_even contains 0 while the argument is 3.
We ran the following command to check whats wrong with the echo "3 % 2" | bc -l construction since without using that construction we could get the script working:
$ echo "3 % 2" | bc -l
0
Then we ran bc in the terminal and ran 3 % 2 which gave 1 as the proper output.
Can somebody please explain what is happening here?
Check this explanation as to bc -l calculates a % b differently from plain bc without the -l. The quick solution is to set your scale back to zero:
$ bc -l <<< "scale=0; 3 % 2"
1
But I would probably do this without using bc at all, since bash includes sufficient functionality to calculate integer remainders. If all you need is integer math, bash may be good enough on its own.
#!/usr/bin/env bash
echo "$1"
odd_even=$(($1 % 2))
echo "$odd_even"
if [[ $odd_even -eq 0 ]]; then
echo "even"
else
echo "odd"
fi
My results:
$ bash remtest.sh 3
3
1
odd
$ bash remtest.sh 4
4
0
even
another option:
#!/bin/bash
var=$1
if [[ $((var % 2)) -eq 0 ]];
then echo "$var is even";
else echo "$var is odd";
fi

Check if every argument is an integer in shell

I've been killing myself over this trying to figure it out, and I know it's probably super simple, so hoping a new pair of eyes can help. I have a Bourne shell (sh) script that I'm writing and it takes a list of integers as the input (and amount from 1 integer up, ideally I'd like to take both positive and negative ints). I'm trying to do an error check for the case if someone inputs something other than an integer. They could input "1 2 3 4 5 a" and it'd give an error, because the a is not an int.
I have an error check for no inputs that works, and I have code that does stuff to the list of integers themselves, but even when strings are given it still gets to my final code block.
I currently have a for loop to iterate through each item in the list of integers, then an if loop to give the error message if the argument in question isn't an int. I've tried a few different versions of this, but this is the most recent one so I've put it below.
for i in $#; do
if [ $i -ge 0 ] 2>/dev/null; then
echo "Invalid input: integers only."
exit 1
fi
done
#!/bin/sh
#
for i in "$#"
do
case "${i#[-+]}" in
0)
echo cannot be 0?
exit 1
;;
*[!0-9]* | '')
echo not int
exit 2
;;
esac
done
echo i\'m ok
This should work, for both positive and negative ints. And if you admit that 0 is an integer, just delete the first case.
Almost duplicate: BASH: Test whether string is valid as an integer?
And here is a good answer for posix. https://stackoverflow.com/a/18620446/7714132
You could use a regex:
my_script.sh
for i in $# ; do
if ! [[ "$i" =~ ^-?[0-9]+$ ]] ; then
echo "Invalid input: integers only."
exit 1
fi
done
Example:
$ sh my_script.sh 1 2 3 4
$ sh my_script.sh 1 2 -12
$ sh my_script.sh 1 2 -12-2
Invalid input: integers only.
$ sh my_script.sh 1 2 a b
Invalid input: integers only.
Explanation of the regex:
^: beginning of the string
-?: 0 or 1 times the character -
[0-9]+: 1 or more digit
$: end of the string
In POSIX sh, you can match your string against a glob with case:
#!/bin/sh
for i
do
case "$i" in
*[!0-9]*)
echo "Integers only" >&2
exit 1
esac
done
echo "Ok"
Here's how it runs:
$ ./myscript 1 2 3 4 5
Ok
$ ./myscript 1 2 3 4 5 a
Integers only
The problem with your approach is primarily that you're checking for success rather than failure: [ will fail when the input is invalid.

For loop structure to add in bash

I'm new to this and what I'm trying to do is create a simple adding script in bash.
I have to use a for loop. What I'm starting so far looks like this:
#!/bin/bash
sum=0
for num in {1..15}
do
echo $num
done
echo$sum
I need help with how to make the for loop show for example if I type:
add 4 -3 2 8
it will output as:
4
-3
2
8
=11
How would I make it so the $num only show what I typed in such as the '4 -3 2 8' and negative numbers?
You can use $# to get all parameters, and $(()) to do arithmetic.
sum=0
for num in $#
do
sum=$((sum + num))
done
echo $# = $sum
I'll retag your question as bash; d is not appropriate.
I'm trying to create an exit error to expand on the previous script now. if I type anything but a number now and what I have tried so far is:
sum=0
for num in "$#"
do
echo $num | grep -i [^0-9+-]
if ["$?" = 1] then
echo "Sorry, '$num' is not a number"
fi
sum=$((sum + num))
done
echo $sum
Example if I type in
add 1 2 3 four five
it would say
four
Sorry, 'four' is not a number

For loop in shell script with integer as input

I am trying to take integer as a input and trying to print numbers from 1 to the input number.
How can I do that?
Something like this will work:
read -p "Loop until: " n
for i in $(seq 1 $n); do
echo $i;
done
$n will contain the user input.
The seq program simply builds a sequence of numbers from 1 to $n, and the for loop prints every item in this sequence.
Instead of using seq command you can use the arithmetic initialisation in a shell.
You can use the following code to do it.
$ cat test
#!/bin/bash
read -p "Loop until: " n
a=1
while true; do
if [ $a -le $n ]; then
echo $a
else
break
fi
a=$(($a+1))
done
$ sh test
Loop until: 4
1
2
3
4

Resources