LinuxQuestions.org
Latest LQ Deal: Complete CCNA, CCNP & Red Hat Certification Training Bundle
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 09-28-2012, 10:28 PM   #1
Tiago85
LQ Newbie
 
Registered: Sep 2012
Posts: 5

Rep: Reputation: Disabled
Unhappy Help with function in script


Hi.

I'm new in linux and I'm trying to make a function that takes two string arguments and check if the first is included on the second.

I've made the following code but I'm getting the "syntax error near unexpected token 'then'". The error is at line 13.

I can't figure what is the error.

#!/bin/bash

match() {
# arg $1
# arg $2

FOUND=-1

for (( i=0; i<${#2}; i++ ))
do
for (( a=0; a<=${#1}; a++ ))
do
if [ $a == ${#1} ]; then #ERROR LINE
FOUND=$((i+a))
break
fi

if [ ${2:$((i+a)):1} == ${1:$a:1} ];
then
echo "True"
else
echo "False"
break
fi

done

fi
done
}


Thank you.
 
Old 09-29-2012, 01:02 AM   #2
nugat
Member
 
Registered: Sep 2012
Posts: 122

Rep: Reputation: 31
I don't get the same error as you, but I do get an error. I think you have an extra "fi" in there. Look at this copy of your code, formatted for easier reading, with the extra "fi" commented out:

Code:
#!/bin/bash

match() {
# arg $1
# arg $2

  FOUND=-1

  for (( i=0; i<${#2}; i++ )); do
    for (( a=0; a<=${#1}; a++ )); do
      if [ $a == ${#1} ]; then #ERROR LINE
        FOUND=$((i+a))
        break
      fi
      if [ ${2:$((i+a)):1} == ${1:$a:1} ]; then
        echo "True"
      else
        echo "False"
        break
      fi
    done
#fi
done
}
I'm not so sure your code is doing what you want it to do, though...
 
Old 09-29-2012, 01:50 AM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,253

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
Just to be clear, please provide an example of input, both correct and incorrect, so we may understand what your script is attempting to do?

Also, is this homework of some kind? I ask as there are much shorter solutions (assuming I understand what you require, hence first question above).
 
Old 09-29-2012, 04:13 AM   #4
Tiago85
LQ Newbie
 
Registered: Sep 2012
Posts: 5

Original Poster
Rep: Reputation: Disabled
Hi.

nugat, you are right.
I forgot to delete that fi. For debug I have another if condition between the two for's, but I don't need them.
Without that if then fi the script doesn't work too.

grail, unfortunately it's not SOLVED.

The main goal of this script is to compare two strings and check if the first string is included on the second string.
For exemple running ./match.sh "al" "alright" will return true.
Running ./match "all" "alright" will return false.

This is not a homework for any kind of school.
I have/want to learn script language and I found a problem on the internet and I'm try to resolve it.
I'm not asking for a solution to that problem, I'm try to understand why my script is not working.

I have read that this ${1:$a:1} will give me the "a" (number) caracter on the $1 variable.
And I have read that #1 will give me the lenght of $1 variable.

I don't think I will need anything more to solve this question. I just need to understand and solve the error.

Thank you.
 
Old 09-29-2012, 04:22 AM   #5
Weapon S
Member
 
Registered: May 2011
Location: Netherlands
Distribution: Debian, Archlinux
Posts: 240
Blog Entries: 2

Rep: Reputation: 48
Have you tried echoing all your variables in the loops? You might be surprised
BTW grep is a regular expression program. It would solve this in an instant. Regular expressions are things distinct from bash scripts, so pick your poison your interest.
 
Old 09-29-2012, 05:45 AM   #6
Tiago85
LQ Newbie
 
Registered: Sep 2012
Posts: 5

Original Poster
Rep: Reputation: Disabled
Thanks Weapon S.

The problem is that I can not even try my script, because when I run ./match.sh "al" "already" i get the error "syntax error near unexpected token 'then'.
I did not want to try regular expression because if I can't do a simple script, i should learn first the basic and then try hard things.

I'm making this script just to learn, and not to achieve anything.
 
Old 09-29-2012, 05:51 AM   #7
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,253

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
Firstly, my signature mentions marking the problem as SOLVED once you have an answer and not that you need to do it now.

As for the code, I am not really sure I understand the process you are using, but I thought I would point out some issues:
Code:
if [ $a == ${#1} ]; then
1. As your using bash I would promote using [[ over [ as it has more features

2. As the value of $a and ${#1} are both numbers, you should be using -eq and not ==, see man test

3. Instead of [ or [[ you would also be better suited in this instance to use (( as this is the correct bracketing system for testing numbers
Code:
if (( a == ${#1} )); then
Note: Yes the $ sign is not required for variables but still required for parameters

4. Lastly, this test would appear useless as you are in a for loop with 'a' as the counter and ${#1} as the maximum value, hence this test will ALWAYS be true at the end of the loop
and not before.

As an overall for the function, what happens if the length parameter 1 is longer than that of parameter 2? Surely this will end in error as you will step off the end of
the length of the second variable.

Also @ Weapon S, whilst I agree that grep is designed for regular expressions, the following statement is erroneous:
Quote:
Regular expressions are things distinct from bash scripts
As an example:

http://tldp.org/LDP/abs/html/regexp.html
 
Old 09-29-2012, 06:57 AM   #8
Tiago85
LQ Newbie
 
Registered: Sep 2012
Posts: 5

Original Poster
Rep: Reputation: Disabled
Thank you grail.

I have made the changes and now the script doesn't return any error.

Code:
#!/bin/bash

match(){
# agr $1 needle
# arg $2 haystack

if [ -z "$1" ]; then 
	echo "The argument pattern is empty."
	exit 1
fi

if [ -z "$2" ]; then
	echo "The argument text is empty."
	exit 1
fi

if ((${#1} -gt ${#2})); then
	echo "FALSE"
        exit 0
fi

SEARCH=-1

for(( i=0; i<${#2}; i++ ))
do
	if [[ "${2:$i:1}" == "${1:0:1}" ]]; then

		for(( a=0; a<=${#1}; a++ ))
		do
			if (($a -eq ${#1} )); then	
				SEARCH=$((i+a))
				break
			fi

			if(( ${2:$((i+a)):1} == ${1:$a:1} )); then
				echo "True"
			else	
				echo "False"
				break
			fi
		done
	fi
done
exit 0
}

match $1 $2
But when i run ./match2.sh as asd it return the folowing errors.

Code:
$ ./match2.sh as asd
./match2.sh: line 17: ((: 2 -gt 3: syntax error in expression (error token is "3")
./match2.sh: line 30: ((: 0 -eq 2 : syntax error in expression (error token is "2 ")
True
./match2.sh: line 30: ((: 1 -eq 2 : syntax error in expression (error token is "2 ")
True
./match2.sh: line 30: ((: 2 -eq 2 : syntax error in expression (error token is "2 ")
./match2.sh: line 35: ((: d ==  : syntax error: operand expected (error token is " ")
False
When I compare two number and the result is false I get this error. This should not enter on IF condition?
 
Old 09-29-2012, 09:02 AM   #9
nugat
Member
 
Registered: Sep 2012
Posts: 122

Rep: Reputation: 31
Quote:
Originally Posted by Tiago85 View Post
But when i run ./match2.sh as asd it return the folowing errors.

Code:
$ ./match2.sh as asd
./match2.sh: line 17: ((: 2 -gt 3: syntax error in expression (error token is "3")
./match2.sh: line 30: ((: 0 -eq 2 : syntax error in expression (error token is "2 ")
True
./match2.sh: line 30: ((: 1 -eq 2 : syntax error in expression (error token is "2 ")
True
./match2.sh: line 30: ((: 2 -eq 2 : syntax error in expression (error token is "2 ")
./match2.sh: line 35: ((: d ==  : syntax error: operand expected (error token is " ")
False
if i replace those '(( ))' with '[ ]' i don't get that error.

this seems to be a very convoluted way to look for a string though. and why are you comparing numbers if you want to be looking for one string in another?

you can still use grep, as another has mentioned, and still make it a simple script, e.g.:

Code:
#!/bin/bash

match() {
  regex=$1
  string=$2
  echo $string|grep --color $regex && return 0 || return 1
}

[ $# -ne 2 ] && echo "Usage: $0 <REGEX> <STRING>" && exit 1
match $1 $2 && echo MATCH || echo NO MATCH
 
Old 09-29-2012, 09:32 AM   #10
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,253

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
You might need to pay a little closer attention to the information I provided.

When using [ or [[ for numbers you need to use -eq.

When using (( you use ==

Also the simpler test shown by nugat of checking the number of parameters would negate checking each parameter but does introduce the problem
of either parameter being empty. Of course searching for an empty parameter or in an empty one shouldn't cause too many issues (???).

I am guessing you are using the function just to learn these as of course it is not needed in this case.

Finally, bash does not require the added use of grep should you wish to perform your regex. As others have now shown other
solutions, I will add a slightly simpler version:

Code:
#!/bin/bash

match() {
	if [[ $2 =~ $1 ]]
	then
		echo FOUND
	else
		echo NOT FOUND
	fi
}

(( $# == 2 && ${#1} )) || { echo "Usage: $0 <REGEX> <STRING>" && exit 1; }

match "$1" "$2"
This also disallows the regex to be empty. If you are not sure why this is needed, try removing '&& ${#1}' and test for your self.
 
Old 09-29-2012, 09:49 AM   #11
Thad E Ginataom
Member
 
Registered: Mar 2011
Distribution: Ubuntu 12.04 with KXStudio, MATE & Compiz
Posts: 46

Rep: Reputation: 7
Nugat, I am a decade out of practice, and trying to pick up again on this stuff. There has already been a suggestion that you echo variables in a loop. I'd second that, and also suggest that you put this near the top of your scripts for testing:
Code:
set -xv
This will give you lots of information about what the shell is actually doing with your script, and, especially, you will be able to see how variables are being used/substituted/tested. This will help to sort out a host of errors with quotes, command substitutions, tests, etc etc.

I used to use /bin/sh, with some use of ksh. If this advice needs tailoring for bash, then I shall be happy to learn about that from others, please.
 
Old 09-29-2012, 01:33 PM   #12
Tiago85
LQ Newbie
 
Registered: Sep 2012
Posts: 5

Original Poster
Rep: Reputation: Disabled
It's solved
Thank you all for all information that you write.

Now i can move forward.
 
Old 09-29-2012, 01:46 PM   #13
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,253

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
Please use the Thread Tools to mark the question as SOLVED.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Expect script: how do i send function key F12 in an expect script alix123 Programming 4 09-01-2013 10:06 PM
Screen a function in script TheMan7 Linux - Software 3 12-18-2011 04:41 AM
[SOLVED] Getting $1 from a Bash Script that uses a function? cryingthug Programming 7 10-04-2011 10:34 PM
How to cd in a script function? subhrajyotibal Linux - Newbie 2 04-25-2008 02:52 AM
return value of function in script ramesh_manu Red Hat 1 02-18-2007 02:05 PM


All times are GMT -5. The time now is 11:04 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration