LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
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 07-09-2018, 01:53 AM   #16
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,806

Rep: Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207

Aaarg this hurts
-eq is for comparing numbers!
@Shadow_7, do you confuse it with perl where eq compares strings?
 
Old 07-09-2018, 07:56 AM   #17
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,930

Rep: Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321
probably irrelevant, but there is a missing " in line 2:
Code:
   echo "line is $line
you need to add a closing " (if not yet made)
 
Old 07-11-2018, 04:39 PM   #18
Shadow_7
Senior Member
 
Registered: Feb 2003
Distribution: debian
Posts: 4,137
Blog Entries: 1

Rep: Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874
Quote:
Originally Posted by MadeInGermany View Post
Aaarg this hurts
-eq is for comparing numbers!
@Shadow_7, do you confuse it with perl where eq compares strings?
Not confused with perl, as I never really did much in perl. Using so many symbols to type your variables seemed inefficient. But I could be confused with a number of other programming options.

$ if [ "YES" -eq "NO" ]; then echo "true"; fi
bash: [: YES: integer expression expected

Seems like it is for "integer expression"'s.

$ if [ "YES" = "YES" ]; then echo "true"; else echo "false"; fi
true

$ if [ "YES" = "NO" ]; then echo "true"; else echo "false"; fi
false

I used to always get messed up in C because using an = in there SETS THE VALUE, and == is the COMPARE operator. Where setting the value will ALWAYS return true. Baring rare exception, solar flares, faulty hardware, ... The always false option would likely not compile.

$ if [ "YES" == "YES" ]; then echo "true"; else echo "false"; fi
true

$ if [ "YES" == "NO" ]; then echo "true"; else echo "false"; fi
false

In bash I don't think it matters as both seem to work.
 
Old 07-12-2018, 12:21 AM   #19
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,930

Rep: Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321
Quote:
Originally Posted by Shadow_7 View Post
N

I used to always get messed up in C because using an = in there SETS THE VALUE, and == is the COMPARE operator.
In bash you can use == for comparison, that will make the life easier (although = and == are exactly the same - as far as I know).
In bash use strings (like -eq, -gt ...) for numerical comparison and use signs (like =, > ..) for string comparison.
 
Old 07-12-2018, 02:08 AM   #20
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,806

Rep: Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207
Yes, bash treats == like = in the test or [ command.
Because it is a command, you must escape < and > string comparison operators!
See also this

Perhaps you should get used to [[ ]] that is not a command:
== is preferred over =
< and > must not be escaped
$variable does not need quotes because no argument expansion takes place
And it has got a feature:
== treats the right operand as a glob pattern, unless it is quoted.
For demonstration:
Code:
x=55 y=?*
[[ $x == $y ]] && echo match
[[ $x == "$y" ]] && echo equal
The latter is a plain string comparison, as can be done with the [ test command with
Code:
[ "$x" = "$y" ] && echo equal
where the quoting is done for a different reason (and on both sides).

Last edited by MadeInGermany; 07-12-2018 at 02:10 AM.
 
Old 07-12-2018, 03:42 AM   #21
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,930

Rep: Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321
[ can be a bash built-in and/or a binary: /usr/bin/[
test is the same as /usr/bin/[
[[ is only a built-in command
 
Old 07-12-2018, 08:43 AM   #22
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,806

Rep: Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207
In fact on most Unix OS (but not GNU/Linux) there is a link /usr/bin/[ --> /usr/bin/test
And when /usr/bin/test is invoked as [ it just requires a closing ] as the last argument.

In contrast, the [[ ]] is a built-in, and [[ is not a command.
Within [[ ]] the shell uses a different parser that avoids the problems with the command parser.

The only drawback with [[ ]] is that it is not yet standardized (Posix).
It works in bash/ksh/zsh but maybe not in /bin/sh.
 
Old 07-12-2018, 04:07 PM   #23
bkelly
Member
 
Registered: Jan 2008
Distribution: Centos 7-4
Posts: 205

Original Poster
Rep: Reputation: 13
I am new at Linux and Bash. I think I have gotten off track and I don’t understand most of what has been posted. I do not understand the post of GazL at all. MadeInGermany writes about “case” then the code does not look like case at all. Well, not what I am accustomed do.
The first part of my bash script builds a file that is a list of files to look for. In there I decided to put some comments and create them with the # as the first character. That seems to be in keeping with the Linux scripting concept. Now I want the IF statement to skip over them.
The second part does some greps and has that noted if statement. Right now that segment of code looks like this:

Code:
echo “4 line is $LINE >> $LIST_OF_REFERENCES
if [[ “$line” == “#*” ]];
then
    echo “hash found”
else
    echo “hash not found”
fi
The echo statement does output a line beginning with the 4 character and the contents of each line.
The first three lines of the file have the character # as the first character. The first part of the if is never taken. I don't understand why not.

Last edited by bkelly; 07-12-2018 at 04:22 PM.
 
Old 07-12-2018, 04:32 PM   #24
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,806

Rep: Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207
Agreed we went a bit off with an experts discussion.
Still you should be able to get your bits out of the many posts.
Here is the annotated correction for your initial post:
Code:
while IFS= read -r line; do
   echo "line is $line"
# The " at the end was missing!
   if [[ "$line" != "#"* ]]; then
# The * is a glob match (or wildcard) character
# Only [[ ]] provides safe glob matches
# The literal # must be escaped: \# or "#" or '#'
      echo "# not found"
   else
      echo "# was found"
   fi
done
And your previous post:
Code:
if [[ "$line" == "#"* ]]
# The literal # must be escaped but not the * (unless you want to compare with a literal *)
then
    echo "hash found"
else
    echo "hash not found"
fi
 
Old 07-12-2018, 04:33 PM   #25
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.9.2009
Posts: 5,734

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
Yes, there has been a lot of discussion and opportunities for learning here. It's been a most enlightening thread, IMO.

Code:
echo “4 line is $LINE >> $LIST_OF_REFERENCES
if [[ “$line” == “#*” ]];
then
    echo “hash found”
else
    echo “hash not found”
fi
Couple of obvious things. First, is the variable $LINE or $line? ...they are not the same. Case matters.
Use the correct variable name in the if statement.

Re-read the posts and find the one that tells you how to write the regexp for the match.
You are currently trying to match a line that is equal to "#*" That is, one that contains only a "shesplat".

[Oh...MadeInGermany reposted it for you...]


Did you ever put set -x in the script so you could see what it is doing?

[Part of the reason we've been rambling is your 6-day absence...more frequent feedback from you would be helpful, IMO]

Last edited by scasey; 07-12-2018 at 05:03 PM.
 
Old 07-12-2018, 05:44 PM   #26
bkelly
Member
 
Registered: Jan 2008
Distribution: Centos 7-4
Posts: 205

Original Poster
Rep: Reputation: 13
scasey,
Sorry about the delay, yes, that makes it a bit difficult. I went through a bunch of iterations today and the working code, only the essential bits, is:

Code:
if [[ "$line" == "#"* ]];
then
   echo "found"
else
   echo "not found"
fi
The # character is not escaped. Then I simplified the IF to

Code:
if [ "$line" == "#"* ];
using only single brackets and it did not work.
OK, so that is the way it is.
I thank each of you for your time and patience with me.

Quite a while ago I coined this phrase and told my boss. I still use it:

The hard stuff?
I do that every day.
Its the easy stuff that kicks my ass!

Last edited by bkelly; 07-12-2018 at 05:45 PM.
 
Old 07-12-2018, 06:06 PM   #27
bkelly
Member
 
Registered: Jan 2008
Distribution: Centos 7-4
Posts: 205

Original Poster
Rep: Reputation: 13
And I just discovered something surprising. This works:

Code:
if [[ "$line" == "#"* ]];
then
   echo "found"
else
   echo "not found"
fi
but this does not work

Code:
if [[ "$line" == "#"* ]];
then
#   echo "found"
else
   echo "not found"
fi
If seems the IF cannot take a null set of commands. That's not very nice.
 
Old 07-12-2018, 06:24 PM   #28
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
For this type of stuff, I prefer filter comments before the read lines loop

Code:
while read -r line; do
  # do any job with $line
  echo $line
done < <(grep -v ^# /path/to/file)
edit, same as grail posted in previous page

Last edited by keefaz; 07-12-2018 at 06:26 PM.
 
Old 07-12-2018, 06:49 PM   #29
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.9.2009
Posts: 5,734

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
Quote:
Originally Posted by bkelly View Post
scasey,
Sorry about the delay, yes, that makes it a bit difficult. I went through a bunch of iterations today and the working code, only the essential bits, is:

Code:
if [[ "$line" == "#"* ]];
then
   echo "found"
else
   echo "not found"
fi
The # character is not escaped. Then I simplified the IF to

Code:
if [ "$line" == "#"* ];
using only single brackets and it did not work.
OK, so that is the way it is.
I thank each of you for your time and patience with me.

Quite a while ago I coined this phrase and told my boss. I still use it:

The hard stuff?
I do that every day.
Its the easy stuff that kicks my ass!
MadeInGermany explained why that is in #14
 
Old 07-12-2018, 06:51 PM   #30
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.9.2009
Posts: 5,734

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
Quote:
Originally Posted by bkelly View Post
And I just discovered something surprising. This works:

Code:
if [[ "$line" == "#"* ]];
then
   echo "found"
else
   echo "not found"
fi
but this does not work

Code:
if [[ "$line" == "#"* ]];
then
#   echo "found"
else
   echo "not found"
fi
If seems the IF cannot take a null set of commands. That's not very nice.
Your second snippet simply says to do nothing if the test matches. Why do you think that doesn't work?
 
  


Reply



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
How to get some bash scripts into a simple bash script with some echo and if statement. y0_gesh Programming 3 03-01-2012 09:46 AM
Strange if statement behaviour when using bash/bash script freeindy Programming 7 08-04-2008 06:00 AM
BASH IF statement kinetik Programming 10 05-07-2006 02:48 AM
Bash: Print usage statement & exit; otherwise continue using Bash shorthand operators stefanlasiewski Programming 9 02-07-2006 05:20 PM
bash statement os2 Programming 2 03-20-2005 10:13 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 08:00 PM.

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
Open Source Consulting | Domain Registration