Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am trying to get the number of occurrences in a script and when running the command on the command line, it works fine, but not in a script. Both variables are initialized. FILE_PATH is the absolute path of the file and VARIABLE_NAME is something like firstName or lastName.

VARIABLE_NAME="_firstName"    
grep -cP "\(this\.|\s\){1}$VARIABLE_NAME" $FILE_PATH

When I take $VARIABLE_NAME out of the script and replace it directly with what I am looking for, it works as expected, so it is something with the replacement.

Any ideas what I can try?

share|improve this question
    
Is that really all that line does in your script, print the number of occurrences to stdout, or is it part of some larger command? –  garyjohn May 3 '11 at 16:08
    
It is part of a larger command, but I cannot get this part to work. –  Walter White May 3 '11 at 16:12
    
My point was that if a command works at a shell prompt but not within a script, then there is something different between those two environments and it might be important to the answer to know more about the context in which the command is being executed in the script. –  garyjohn May 3 '11 at 17:04

4 Answers 4

up vote 2 down vote accepted

The problem seems to reside in your regex. can you show us what you are trying to match?

if you are trying to match constructs like this :

this.contentOfVar
  contentOfVar

try it with the following :

grep -cP "(this\.|\s)$VARIABLE_NAME" $FILE_PATH

This works in GNU grep. You don't have to specify {1}, since the default will be 1. With the -P flag on, \( and \) will match literal parenthesis in the string, since this is the perl behavior.

share|improve this answer
    
Ah, you were right, it is a variable that has an underscore in it that is causing issues. –  Walter White May 3 '11 at 17:36

It looks like the problem is with regex escaping. Here is a complete working example of how I would do something like this.

#!/bin/bash

VARIABLE_NAMES=(testOne testTwo)
RE="(this\.|\s){1}"

cat > ./testfile.txt <<EOF
this.testOne
this.testTwo
this.testTwo
this.testOne
this.testTwo
EOF

for VARIABLE_NAME in ${VARIABLE_NAMES[@]}; do
    grep -cP "${RE}${VARIABLE_NAME}" testfile.txt
done

exit 0
share|improve this answer

To add to others' answers, I'd suggest using single-quotes except where you explicitly need something from a variable. For example:

#!/usr/bin/env bash

dosomething | grep -cP 'some stuff'${SOMEVARIABLE}'more stuff';

If you need single-quotes in the regex, it looks a little uglier:

# ...
dosomething | grep -cP 'some stuff'"'"'this part has a single-quote around it'"'"${SOMEVARIABLE}'more stuff';

The benefit of using single quotes is you don't have to escape things.

-Brian

share|improve this answer

It has to do with escaping the quotes and the slashes:

VARIABLE_NAME="_firstName"
FILE_PATH="/tmp/*"
echo grep -cP \"\\\(this\\\.\|\\\s\\\)${VARIABLE_NAME}\" $FILE_PATH
grep -cP \"\\\(this\\\.\|\\\s\\\)${VARIABLE_NAME}\" $FILE_PATH

I added the echo as an example to show how it's actually interpeted.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.