Home > Mobile >  egrep gives me what I want, grep -E does not
egrep gives me what I want, grep -E does not

Time:02-16

I have read that egrep is deprecated in favour of grep -E so I'm looking back at my code and changing it where I find it. But I see that the results are not always as expected.

With egrep, I get my list of running Oracle instances:

ps -ef|grep [p]mon|awk -F'ora_pmon_' '{print $NF}'|egrep -v 'ASM|^$'
halana
bila
halsasa
loana

However with grep -E, I get part of the awk in the results:

ps -ef|grep [p]mon|awk -F'ora_pmon_' '{print $NF}'|grep -Ev 'ASM|^$'
halana
bila
halsasa
 {print $NF}
loana

Excluding 'print' obviously works but is it the right way to go about it?:

ps -ef|grep [p]mon|awk -F'ora_pmon_' '{print $NF}'|grep -Ev 'ASM\|^$|print'
halana
bila
halsasa
loana

Is this effect due to the fact that grep -E allows additional regular expression syntax?

CodePudding user response:

Suggesting to simplify your line, eliminate all grep commands:

pgrep -af 'pmon'|awk -F'ora_pmon_' '!/ASM|^$/{print $NF}'

Fold first grep command into pgrep command.

Fold second grep command into awk scirpt !/ASM|^$/{print $NF}

CodePudding user response:

About grep -E vs egrep

There is no difference whatsoever between these commands (they're even provided by the same executable on most operating systems); your old code was vulnerable to this bug too, and if you didn't see it, that's just a matter of being "lucky" in ps getting enough of the process list read before the shell gets to setting up the awk part of the pipeline.

Solving Your Problem

The right answer is already given by @DudiBoy, but the answer with the smallest possible change would be to make your awk (assuming it has GNU extensions and accepts regexes in the field separator specification) escape the string pmon the same way your first grep command does:

ps -ef|grep '[p]mon'|awk -F'ora_[p]mon_' '{print $NF}'|grep -Ev 'ASM|^$'
  • Related