1

The man page for the pgrep command indicates that the pattern "specifies an Extended Regular Expression for matching against the process names or command lines". Apparently, Extended Regular Expressions are an extension of the regular expressions used in the original UNIX grep command.

I need to be able to match the string 'myProcess' but exclude the string 'test_myProcess' using Extended Regular Expressions. Initially, I assumed that Extended Regular Expressions would support the negative lookbehind assertion, which led me to the following regular expression: (?<!test_)(myProcess). This apparently works for other regular expression tools (I tried it on the Regex101 website).

However, when I try it with pgrep, I get the following error: Invalid preceding regular expression. After looking at some Extended Regular Expression pages, it appears that the negative lookbehind assertion doesn't exist for this type of regular expression (or at least I was unable to find any reference to it). I need to know how to match the string 'myProcess' but exclude the string `'test_myProcess' using Extended Regular Expressions.

Edit: Examples of text I want to match (or not match) Match desired:

  • myProcess
  • /usr/local/bin/myProcess.py
  • /usr/bin/myProcess

Match NOT desired:

  • test_myProcess
  • /usr/local/bin/test_myProcess.py
  • /usr/bin/test_myProcess

Right now, I am toying with the idea of running pgrep twice, once matching 'myProcess' and once matching 'test_myProcess' and taking the difference of the two results as the correct answer. However, I am definitely interested in alternative solutions.

Edit: Note that the process name itself will not include 'myProcess'. It will simply appear in the command-line for that process. The process name will most likely be python2.7. And, 'myProcess' is not guaranteed to occupy either the beginning or the end of the string. Also, as pointed out, I want to match the string if 'myProcess' is present but not if 'test_myProcess' is also present.

3 Answers3

2

After quite a bit of discussion with @don_crissti, the final solution was

ps auxf | grep -E '[m]yProcess' | grep -vE 'test_[m]yProcess'

This will first get all the lines containing 'myProcess' and then match all lines NOT containing the lines with 'test_myProcess' (the -v inverts the match). The -E coupled with the brackets simply serves to prevent matching the two grep processes that will be listed in the ps output. This turned out to be much simpler than trying to find one regex to rule them all. Thank you all for your help.

  • You could've also used ps auxf | grep -P (?<!test_)myProcess since you were trying to use perl-compatible regular expressions, not mere extended regular expressions. – Joe Sewell Dec 17 '20 at 20:00
1

(?<!) is a perl regexp operator. The specification for the standard ERE can be found here.

Sounds like here you want to find processes whose argument list either starts with myProcess or contains /myProcess.

So:

pgrep -f '(^|/)myProcess'
0

So, you want to pgrep the processes whose name starts with "myProcess"? Then use the regex ^myProcess:

pgrep '^myProcess'

In a regex, the ^ character means that what follows has to be found at the beginning of the string.

Example:

$ pgrep -a app 
3267 nm-applet
3280 /usr/bin/python /usr/share/system-config-printer/applet.py
3297 /usr/lib/mate-panel/wnck-applet
3306 /usr/lib/mate-panel/clock-applet

$ pgrep -a '^app'
3280 /usr/bin/python /usr/share/system-config-printer/applet.py
xhienne
  • 17,793
  • 2
  • 53
  • 69
  • Unfortunately the process name does not necessarily begin that way. In fact, the process name is python2.7, but the command-line is different depending on where the script I am running is installed. It will have 'myProcess' somewhere in the command-line (I use pgrep -f) – tintedFrantic Jan 17 '17 at 20:48
  • @tintedFrantic Can you edit your question and give a real world example please? You example is misleading. – xhienne Jan 17 '17 at 20:49
  • @don_crissti I will edit the question title. Thank you. – tintedFrantic Jan 17 '17 at 21:01