2

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?

3
  • 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, 2011 at 16:08
  • It is part of a larger command, but I cannot get this part to work.
    – Walter
    May 3, 2011 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, 2011 at 17:04

4 Answers 4

2

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.

1
  • Ah, you were right, it is a variable that has an underscore in it that is causing issues.
    – Walter
    May 3, 2011 at 17:36
0

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
0

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

0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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