Nested loop in shell - linux

I am a beginner at shell programming. I have a problem related to nested loops in shell scripts. I want to get output like this:
Input: 4
Output:
*
**
***
****
This is the script I am using so far:
echo "input : "
read a
for ((i=0; i<a; i++))
do
for ((j=0; j<i; j++))
do
echo "*"
done
echo "\n"
done
When trying to execute my program I get an error: Bad for looping.
Thanks in advance.

try this
echo "input : "
read a
for ((i=0; i<a; i++))
do
for ((j=0; j<=i; j++))
do
printf "*"
done
echo
done
To not print newlines, you can use printf (or the echo -n but is not as portable as printf)

I don't get any error with the script! Though the echo needs to be different like below:
echo "input : "
read a
for ((i=0; i<a; i++))
do
for ((j=0; j<i; j++))
do
echo -ne "*"
done
echo -ne "\n"
done
You might try adding $ in front of the variables while accessing them though.
It is not giving any errors for me.

#!/bin/bash
print_starry_row()
{
n="$1"
for ((i=0;i<n;i++))
{
echo -n "*"
}
echo
}
read -p "Enter number of stars? " num
if [[ "$num" -eq $num ]]
then
for ((i=1;i<=num;i++))
{
print_starry_row $i
}
else
echo "You must enter a valid integrer"
fi

Related

Why doesn't string comparison with wildcards work properly?

I wrote this shell code, but it doesn't get the good output.
Even though the $csoport gets the "...: No such user" output, id doesn't echoes the following line I wrote there.
read felhasznalo
while [ "$felhasznalo" != "exit" ]
do
csoport=`groups $felhasznalo`
echo "$csoport"
if [[ "$csoport" == *": No such user"* ]] ; then
echo -n "Nincs ilyen felhasznalo a rendszerben"
else
echo "$csoport"
fi
echo -n "Felhasznalo: "
read felhasznalo
done
You shouldn't try to match the error messsage since you only care if groups fails. You ought to do:
if ! csoport=$(groups "$felhasznalo"); then
printf "Nincs ilyen felhasznalo a rendszerben"
else
echo "$csoport"
fi

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...

shell script concatenate with space two string

I’ve a shell script which need to provide the following pattern in the txt file
test0000 test0000#gmail.com
test0001 test0001#gmail.com
and so on until the stop condition (10 in this case...)
currently its not working and I tried with the following:
start=“test”
email=“#gmail.com"
start=0
stop=10
i=0
while [[ $i -le 10 ]]
do
printf "%s%10d\n" "$start” "$i" "\n" "$start” "$email"
any idea how to resolve it ? I got error: "#gmail.com:" invalid number
One more example with a different for loop syntax:
start="test"
email="#gmail.com"
for i in {0000..9};do
echo "${start}$i ${start}${i}${email}"
done
test0000 test0000#gmail.com
test0001 test0001#gmail.com
test0002 test0002#gmail.com
test0003 test0003#gmail.com
test0004 test0004#gmail.com
test0005 test0005#gmail.com
test0006 test0006#gmail.com
test0007 test0007#gmail.com
test0008 test0008#gmail.com
test0009 test0009#gmail.com
Or, with while loop:
start="test"
email="#gmail.com"
count=0
while [[ $count -lt 10 ]]; do
printf '%s%04d %s%04d%s\n' "$start" $count "$start" $count "$email"
let count++
done
You can use:
start='test'
email='#gmail.com'
for ((i=0; i<10; i++)); do
printf '%s%04d %s%04d%s\n' "$start" $i "$start" $i "$email"
done
test0000 test0000#gmail.com
test0001 test0001#gmail.com
test0002 test0002#gmail.com
test0003 test0003#gmail.com
test0004 test0004#gmail.com
test0005 test0005#gmail.com
test0006 test0006#gmail.com
test0007 test0007#gmail.com
test0008 test0008#gmail.com
test0009 test0009#gmail.com

Bash: Counting instances of a string in text file with a loop

I am trying to write a simple bash script in which it takes in a text file, loops through the file and tells me how many times a certain string appears in the file. I want to eventually use this for a custom log searcher (for instance, search for the words 'log in' in a particular log file, etc.), but am having some difficulty as I am relatively new to bash. I want to be able to quickly search different logs for different terms at my will and see how many times they occur. Everything works perfectly until I get down to my loops. I think that I am using grep wrong, but am unsure if that is the issue. My loop codes may seem a little strange because I have been at it for a while and have been constantly tweaking things. I have done a bunch of searching but I feel like I am the only one who has ever had this issue (hopefully not because it is incredibly simple and I just suck). Any and all help is greatly appreciated, thanks in advance everyone.
edit: I would like to account for every instance of the string and not just
one instance per line
#!/bin/bash
echo "This bash script counts the instances of a user-defined string in a file."
echo "Enter a file to search:"
read fileName
echo " "
echo $path
if [ -f "$fileName" ] || [ -d "$fileName" ]; then
echo "File Checker Complete: '$fileName' is a file."
echo " "
echo "Enter a string that you would like to count the occurances of in '$fileName'."
read stringChoice
echo " "
echo "You are looking for '$stringChoice'. Counting...."
#TRYING WITH A WHILE LOOP
count=0
cat $fileName | while read line
do
if echo $line | grep $stringChoice; then
count=$[ count + 1 ]
done
echo "Finished processing file"
#TRYING WITH A FOR LOOP
# count=0
# for i in $(cat $fileName); do
# echo $i
# if grep "$stringChoice"; then
# count=$[ $count + 1 ]
# echo $count
# fi
# done
if [ $count == 1 ] ; then
echo " "
echo "The string '$stringChoice' occurs $count time in '$fileName'."
elif [ $count > 1 ]; then
echo " "
echo "The string '$stringChoice' occurs $count times in '$fileName'."
fi
elif [ ! -f "$fileName" ]; then
echo "File does not exist, please enter the correct file name."
fi
To find and count all occurrences of a string, you could use grep -o which matches only the word instead of the entire line and pipe the result to wc
read string; grep -o "$string" yourfile.txt | wc -l
You made basic syntax error in the code. Also, the variable of count was never updating as the the while loop was being executed in a subshell and thus the updated count value was never reflecting back.
Please change your code to the following one to get desired result.
#!/bin/bash
echo "This bash script counts the instances of a user-defined string in a file."
echo "Enter a file to search:"
read fileName
echo " "
echo $path
if [ -f "$fileName" ] ; then
echo "File Checker Complete: '$fileName' is a file."
echo " "
echo "Enter a string that you would like to count the occurances of in '$fileName'."
read stringChoice
echo " "
echo "You are looking for '$stringChoice'. Counting...."
#TRYING WITH A WHILE LOOP
count=0
while read line
do
if echo $line | grep $stringChoice; then
count=`expr $count + 1`
fi
done < "$fileName"
echo "Finished processing file"
echo "The string '$stringChoice' occurs $count time in '$fileName'."
elif [ ! -f "$fileName" ]; then
echo "File does not exist, please enter the correct file name."
fi

error in if else in bash

i=0
EDA="xx7p2"
while read line
do
echo "i is --- $i"
echo " PACKAGE IS - --$EDA--"
#echo $line "\n"
if (( $i > 0 ))
then
package=$(echo $line | awk '{print $1}')
echo "EDA PACKAGE IN LOOP IS ---$Eda_package---"
if [ "$package" == "$EDA" ] ; then
#then
well_bias=$(echo $line | awk '{print $2}')
biasmap=$(echo $line | awk '{print $3}')
unified=$(echo $line | awk '{print $4}')
echo "eda pack --$package bias is --$wel biasmap is --$biasmap unified- --$unified"
fi
fi
i=$((i+1))
done < config.list
Here the statements inside the second if statement is not executed even if the two variables are same. Am I missing something here?
Make a simplified version of your problem to get it nailed down.
I can't reproduce your problem with this sample script:
#!/bin/bash
i=$1
a=$2
while read line
do
if (( $i > 0 ))
then
echo "1st if "+$i
if [ "$a" == "foo" ] ; then
echo "2nd if"
fi
fi
i=$((i+1))
done < nfoo.sh
called nfoo.sh and calling it ./nfoo.sh 4 bar, ./nfoo.sh -4 bar, ./nfoo.sh 4 foo and ./nfoo.sh -4 foo.
Might your error be in the package-assignement? You don't need awk for such a simple task. For a single word, to just extract the first word, you would use echo ${line/ */} while I see nothing wrong in your awk-statement.
Since you extract more arguments, I would suggest an array:
#!/bin/bash
i=$1
a=$2
while read line
do
if (( $i > 0 ))
then
arr=($line)
echo "1st if "+$i
if [ "if" == "${arr[0]}" ] ; then
echo "2nd if: " $line
fi
fi
i=$((i+1))
done < nfoo.sh
Btw.: Where is the else, the headline is talking about?
UPDATE: based on more testing with the small script below:
Having the $ as part of the string in package variable was a problem for me. If I escape it with a \$ I get it to work with the correct comparison operator mentioned below.
Use this for comparison (note the space before/after the =)
if [ "$package" = "$EDA" ] ; then
Without the space the expression seems to evaluate always to true. (Also, as an aside, using == without spaces before/after will result in an [: 11: $EDAx: unexpected operator)
I used this small script for testing, you can use to verify your own constructs, hope it's helpful. This works correctly as shown
#!/bin/bash
package="\$EDA"
echo $package
if [ "$package" = "\$EDA" ] ; then
echo "The same"
else
echo "Not the same"
fi
Note1: I added the else to be certain of the outcome of the comparison, as your script doesn't contain any else
Note2: It's always better to explicitly specify what shell to run rather than to depend on some external implicit environment settings, so I would recommend you add the #!/bin/bash to your script, it certainly won't hurt.
Other Comparison Operator from the Advanced Bash-Scripting Guide shows:
string comparison
=
is equal to
if [ "$a" = "$b" ]
Note the whitespace framing the =.
if [ "$a"="$b" ] is not equivalent to the above.
== is equal to
if [ "$a" == "$b" ]
This is a synonym for =.

Resources