BASH - grep - работает в командной строке, но не в скрипте

4698
Walter

Я пытаюсь получить количество вхождений в сценарии, и при запуске команды в командной строке она работает нормально, но не в сценарии. Обе переменные инициализируются. FILE_PATH - это абсолютный путь к файлу, а VARIABLE_NAME - это что-то вроде firstName или lastName.

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

Когда я беру $ VARIABLE_NAME из сценария и заменяю его непосредственно на то, что я ищу, он работает как положено, поэтому что-то с заменой.

Есть идеи, что я могу попробовать?

2
Это действительно все, что делает эта строка в вашем скрипте, выводить число вхождений на стандартный вывод или это часть какой-то более крупной команды? garyjohn 13 лет назад 0
Это часть большой команды, но я не могу заставить эту часть работать. Walter 13 лет назад 0
Я хотел сказать, что если команда работает в приглашении оболочки, но не в сценарии, то в этих двух средах есть что-то разное, и для ответа может быть важно узнать больше о контексте, в котором команда выполняется в скрипт. garyjohn 13 лет назад 0

4 ответа на вопрос

2
Yab

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 , 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.

Ах, вы были правы, это переменная с подчеркиванием, которая вызывает проблемы. Walter 13 лет назад 0
0
h0tw1r3

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)" cat > ./testfile.txt <<EOF this.testOne this.testTwo this.testTwo this.testOne this.testTwo EOF for VARIABLE_NAME in $; do grep -cP "$$" testfile.txt done exit 0 
0
pbsmind

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

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

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

0
Brian Vandenberg

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'$'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'"'"$'more stuff'; 

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

-Brian

Похожие вопросы