2

I have the input below:

csdi_d_trs_proc_uxs1        26 24
csdi_d_tdp_process_uxs1     28 32

I only need the line which contains proc. When I use:

grep proc filename 

both lines are output, so I tried using grep -w proc filename, but no output is getting displayed.

How can I get the line which has only proc but not process?

3
  • 3
    why not to use grep '_proc_' instead of just grep 'proc'? Option -w is for words and _ is not a word delimiter. Jun 15, 2017 at 7:49
  • and how this line csdi_d_trs_11proc-_uxs1 26 24 should be treated? Jun 15, 2017 at 7:54
  • 1
    @Roman presumably it's out of scope for the question so the result of any solution would be undefined for this value. Jun 15, 2017 at 17:51

2 Answers 2

12

The -w flag for grep will make the given expression match only whole words.

A "word" is a string of "word characters" surrounded by "non-word characters" (or start/end of line).

The issue in your case is that _ (underscore) happens to be a "word character", and does therefore not serve to delimit the word proc as a word on its own.

Instead of using -w with grep, use a pattern that explicitly delimits the word by _:

grep '_proc_' filename

Alternatively, use [^a-z] instead of _ if you want to delimit the word by anything that is not a lower-case alphabetical character:

grep '[^a-z]proc[^a-z]' filename

Note that this won't recognize proc as a word at the very start/end of a line though.

0
4

-w, --word-regexp Select only those lines containing matches that form whole words. [...] Word-constituent characters are letters, digits, and the underscore.

The underscore is valid as part of an identifier in most programming languages (at least C, Perl, shell), which is probably why it's considered a "word-character" here.

One way to match just word would be to use the negative look-ahead and look-behind tests that Perl regexes provide. Here (?<![a-z]) means "not preceded by a lower case character, and (?![a-z]) similarly for what comes after. The beginning and end of the line aren't lower case characters, so this will match proc even at the beginning:

pcregrep '(?<![a-z])proc(?![a-z])' filename 

Or with a grep ERE, taking the beginning and end of a line explicitly into account:

grep -E '(^|[^a-z])proc([^a-z]|$)' filename

(I'm not sure which one of those is prettier.)

If you have natural-language text, [[:alpha:]] might be more correct than [a-z].

But of course, just grepping for _proc_ is easier, if you know the underscores will be there.

1
  • grep 'proc' filename worked for me.Thanks kusal for your reply Jun 16, 2017 at 6:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .