Using grep with test and without using [[ ]]


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Using grep with test and without using [[ ]]
# 1  
Old 01-22-2019
Using grep with test and without using [[ ]]

As an exercise, I'm trying to re-write this code without the compound square brackets, using grep and test. Need to know what to do about the "equal-tilde".
Code:
#!/bin/bash
# test-integer2: evaluate the value of an integer.
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
if [ "$INT" -eq 0 ]; then
echo "INT is zero."
else
if [ "$INT" -lt 0 ]; then
echo "INT is negative."
else
echo "INT is positive."
fi

# 2  
Old 01-22-2019
Welcome to the forum.


The "equal-tilde" is explained in man bash's "Compound Commands" paragraph:

Quote:
An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
You can use your regex (almost) as given in a grep command:
Code:
grep "^[-0-9]\+$" <<<  "$INT"

The + needs to be escaped as grep uses basic regexes by default. For the rest of your request, just replace the [ with test and drop the ] . Please be aware that your script is missing two fi statements. And, reasonable indentation improves readability and understandability of your code.


Code:
if grep "^[-0-9]\+$" <<<  "$INT"
  then  if test "$INT" -eq 0 
          then  echo "INT is zero."
          elif  test "$INT" -lt 0 
            then        echo "INT is negative."
            else        echo "INT is positive."
        fi
  else  echo "No int"
fi

These 3 Users Gave Thanks to RudiC For This Post:
# 3  
Old 01-22-2019
Instead of converting the ERE to a BRE (that allows some unintended strings like -5-2, ---, and even just - to be considered to be a valid number), we could just tell grep to process its input treating the regex as an ERE and to exit with a zero exit code if and only if a matching line was found:
Code:
if grep -Eq '^-?[0-9]+$' <<< "$INT"; then

P.S. But, of course, Xubuntu56 will also have to fix his/her code to have an fi to match each if.

Last edited by Don Cragun; 01-22-2019 at 06:26 PM.. Reason: Add PS.
These 2 Users Gave Thanks to Don Cragun For This Post:
# 4  
Old 01-22-2019
Thanks so much, guys! This place is great! Looking forward to learning bash.
This User Gave Thanks to Xubuntu56 For This Post:
# 5  
Old 01-23-2019
grep is an external command, that's a (small) overhead.
To only use shell builtins, you can try to convert the RE to a glob (or multiple globs), and use it in a case-esac.
The glob match is less powerful, and often will look ugly - a reason to hide it in a function.
Code:
is_int(){
# error if $1
#   contains a character that is not a dash or digit
#   is empty
#   is dash only
#   has a dash not at the first position
  case $1 in
  *[!-0-9]*|""|-|*?-*) return 1;;
  esac
  return 0
}

INT=-5
if is_int "$INT"; then
  if [ "$INT" -eq 0 ]; then
    echo "INT is zero."
  elif [ "$INT" -lt 0 ]; then
    echo "INT is negative."
  else
    echo "INT is positive."
  fi
fi


Last edited by MadeInGermany; 01-23-2019 at 04:58 AM..
These 2 Users Gave Thanks to MadeInGermany For This Post:
# 6  
Old 01-23-2019
This suggestion relies on bash parameter expansion and test, and gets rid of the need for grep altogether. On the down side you need an intermediary variable:
Code:
zzz=${INT#-}                  # removes the negative sign, if it exists
if test -z "${zzz//[0-9]/}"   # removes all digits; resulting string should be zero length
then 
   test ${INT} -lt 0 && printf "%s is negative\n" ${INT}
   test ${INT} -eq 0 && printf "%s is zero\n" ${INT}
   test ${INT} -gt 0 && printf "%s is positive\n" ${INT}
fi

Naturally the ${param//string/replacement} construct isn't POSIX-compliant.

Another alternative to using grep is expr:
Code:
expr "$INT" : '-\?[0-9][0-9]*$'

but while that works with GNU expr, the Solaris versions (there are FOUR versions on my Sol 10 system!) do not accept the \? construct.

Andrew
These 2 Users Gave Thanks to apmcd47 For This Post:
# 7  
Old 01-23-2019
Hi MadeInGermany...
(Or anyone...)

Relative to this thread as you have used 'case....esac':
What is the reasoning behind ;;, why 2 semicolons instead of 1, after each command inside a 'case' statement?
I have always wondered as I can't find any mention of it.
A question to help our newbie friend to understand too.
Code:
Last login: Wed Jan 23 12:04:15 on ttys000
AMIGA:amiga~> help case
case: case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
    Selectively execute COMMANDS based upon WORD matching PATTERN.  The
    `|' is used to separate multiple patterns.
AMIGA:amiga~> _

And from the manual, (man bash):
Code:
       case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
              A case command first expands word, and tries to match it against
              each pattern in turn, using the same matching rules as for path-
              name expansion (see Pathname  Expansion  below).   The  word  is
              expanded  using  tilde  expansion, parameter and variable expan-
              sion, arithmetic  substitution,  command  substitution,  process
              substitution  and  quote  removal.   Each  pattern  examined  is
              expanded using tilde expansion, parameter  and  variable  expan-
              sion, arithmetic substitution, command substitution, and process
              substitution.  If the shell option nocasematch is  enabled,  the
              match  is  performed  without  regard  to the case of alphabetic
              characters.  When a match is found, the  corresponding  list  is
              executed.   After  the  first  match,  no subsequent matches are
              attempted.  The exit status is zero if no pattern matches.  Oth-
              erwise,  it  is  the exit status of the last command executed in
              list.

This User Gave Thanks to wisecracker For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Is it correct? if test grep EOF $a ...

read a if test grep EOF $a then echo yes file else echo no fi (1 Reply)
Discussion started by: iamsumibisht
1 Replies

2. Shell Programming and Scripting

Grep/print/ a test file

cat abc.txt Filename: SHA_AED_Monthly_SNR_20150331.txt.gz Data Format: ASCII with carriage returns and linefeeds Compression: GZIP GZIP Bytes: 36893068 Unzipped Bytes : 613794510 Records: 851310 Record Length: 738 Blocksize: 32472 Filename: SHA_AED_SNR_ChangeLog_20150331.txt.gz Data... (16 Replies)
Discussion started by: dotran
16 Replies

3. Shell Programming and Scripting

If test grep.... always returns 0 status

Hi all. I am trying to compare and filter two files. I have a bigfile.txt of names and ids and a smallfile.txt of ids only. What I am trying to do is use a while read loop to read the ids in the bigfile and then echo the name and id only if the id exists in the small file. Basically, I'm trying to... (5 Replies)
Discussion started by: jameswatson3
5 Replies

4. Shell Programming and Scripting

searching fileextentions (suffix) with grep and/or test

Hello, I have a problem. I will search files on fileextentions (suffix). It can with the command find, but I will do it with the commands grep and/or test. When i start the script I will see all files with that extention (suffix). Can anyone help me, please? Thanks! Regards, Arjan... (4 Replies)
Discussion started by: arjanengbers
4 Replies

5. Shell Programming and Scripting

How to check weather a string is like test* or test* ot *test* in if condition

How to check weather a string is like test* or test* ot *test* in if condition (5 Replies)
Discussion started by: johnjerome
5 Replies

6. Shell Programming and Scripting

grep functions, how to test if succeeded

Hello ...again. I am stuck on this part, I have a loop with processes an operations file. and calls different functions depending on what is in loop, which processes a database file... #so far my add function works as intended add() { ...blah blah; } # delete is kinda working... (13 Replies)
Discussion started by: gcampton
13 Replies

7. Shell Programming and Scripting

Test on string containing spacewhile test 1 -eq 1 do read a $a if test $a = quitC then break fi d

This is the code: while test 1 -eq 1 do read a $a if test $a = stop then break fi done I read a command on every loop an execute it. I check if the string equals the word stop to end the loop,but it say that I gave too many arguments to test. For example echo hello. Now the... (1 Reply)
Discussion started by: Max89
1 Replies

8. Shell Programming and Scripting

Using grep inside a test

Hi, I want to use grep inside a test statement, but I am getting an error message. Two variables testvarNum=5 testvarNonNum=x echo $testvarNum | grep * The result of this is as follows: 5 However, when I try the following (i.e. to test if the variable is numeric or non-numeric):... (3 Replies)
Discussion started by: dkieran
3 Replies

9. UNIX for Dummies Questions & Answers

Unix grep/test command

Hello, i have a script which checks if the user entered 8 numeric characters in the form of YYYYMMDD (birth date). If the user entered any non numeric characters, an error will be displayed: # Check to see if the 8 characters are all numbers # If not show error essage # And prompt user... (4 Replies)
Discussion started by: netmaster
4 Replies

10. Shell Programming and Scripting

Using grep in a test/if statement

Okay, well this is more or less my first attempt at writing a shell script. Anyways, here's my code: cd ${PATH} if then rm ${FILE} ./anotherScript else exit 1 fi exit 1 Anyways, it's a pretty simple script that is supposed to search for the... (4 Replies)
Discussion started by: cbo0485
4 Replies
Login or Register to Ask a Question