grep seems to always behave case-insensitive

Asked by Jason Murphy

While trying to enforce a minimum password strength i try to use the code
echo $myvar | grep -c [A-Z]
however grep returns 1 line if $myvar has capital letters or not. further testing suggests that grep is acting case insensitive
as it will behave properly with numbers and special characters
there is no alias set for grep
i am using ubuntu 10.10 with latest updates

Question information

Language:
English Edit question
Status:
Solved
For:
Ubuntu grep Edit question
Assignee:
No assignee Edit question
Solved by:
Ralph Corderoy
Solved:
Last query:
Last reply:
Revision history for this message
Jason Murphy (mrdetail123) said :
#1

ok i tested a little more i was wrong, grep acts correctly for the most part
but it still will return 1 line for-
echo test | grep -c [A-Z]
i am thinking that i am doing something wrong but this is so simple that i cannot think what it would be, sorry i still have much to learn

Revision history for this message
Theodotos Andreou (theodotos) said :
#2

If use the --color option you will see the there is no match. But some how it still displays the line!

For example if you try:
  echo test | grep --color '[t]'
You will get:
  test
where both t's are red.

If you try
  echo test | grep --color '[T]'
You get nothing

But if you try
  echo test | grep --color '[A-Z]'
You get
  test
but no colors which implies that there is no match! I am not sure if this is a bug or a "feature" but it is indeed very confusing!

Hope someone can enlight us

Revision history for this message
Manfred Hampl (m-hampl) said :
#3

The -c option of grep instructs grep to output the _number_ of matches

What you most probably wanted to try are commands without the -c option, but maybe with the -i (ignore case) option like

echo test | grep [A-Z]

versus

echo test | grep -i [A-Z]

Revision history for this message
Best Ralph Corderoy (ralph-inputplus) said :
#4

Firstly, it makes it a lot easier if commands and their responses are
pasted directly from the terminal. That way typos aren't introduced
causing confusion and digressions.

Using [A-Z] at the shell may undergoes globbing unless it's quoted; if
you've filename(s) that match in the current directory then they'll
replace the glob pattern, so you normally want to quote the regular
expression if it has [] in it.

Depending on your locale, the character class A-Z may match the 26
upper-case letters or perhaps your locale's collating order is

    aAbBcC...zZ

and in that case A-Z matches all upper and all lower except for `a'.
Alternatively, if it's

    AaBbCc...Zz

then it's all upper and all lower except for `z'.

Try

    echo ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz |
    grep -o '[A-Z]' |
    fmt

to find out what your locale matches.

The correct way to tell grep that you want upper characters is

    grep '[[:upper:]]'

Read the section in the man page that covers `upper' for more detail.

Revision history for this message
Ralph Corderoy (ralph-inputplus) said :
#5

Back to the original problem, if you're trying to count upper-case characters then get tr(1) to delete everything else and then count characters.

    $ echo ABCdef123 | tr -dc '[:upper:]' | wc -c
    3
    $

Revision history for this message
Ralph Corderoy (ralph-inputplus) said :
#6

`grep -c' gives a count of the number of lines that match, not the number of times the regexp matches within the input. So if five matches are on one line it will print 1. Hence me suggesting wc(1) above.

Revision history for this message
Jason Murphy (mrdetail123) said :
#7

thank you Ralph Corderoy for the alternate way to solve my problem, however i have run the tests you suggested and '[A-Z]' only is matching upper case letters. That does not matter now that i know the correct way, thank you all for the input.

Revision history for this message
Jason Murphy (mrdetail123) said :
#8

Thanks Ralph Corderoy, that solved my question.