Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a file that has declarations in it with capital words, something like:

public final Foo BAR;

these declarations are not all uniform. Is there a way for me to grep out just the capital lettered words from the line? I know how to find lines that have capital letters in them, but thats not what I want. I want only the matching capital lettered word. Thanks!

share|improve this question
3  
Have you considered running ctags on your source code and parsing that instead? You will avoid a lot of false-positive matches this way. For example, the solution you ask for will also show capitalized words in comments. –  Warren Young Nov 7 '12 at 20:30

3 Answers 3

up vote 7 down vote accepted

Actually with the -o switch, GNU grep returns only what it has matched. How about:

grep -oP "\w*[A-Z]+\w*" yourfile.txt

Note that this regex will match words with capital letters anywhere in them, not necessarily the beginning. You should tune it to meet your needs if they differ.

As pointed out below, this might not be the most portable of solutions. A portable alternative in Perl is

perl -nE 'say $1  while /(\w*[A-Z]+\w*)/g' yourfile.txt
share|improve this answer
    
That will match words that have a capital anywhere in the word, not necessarily at the beginning. –  bahamat Nov 7 '12 at 20:55
1  
I am aware of that. The OP's example didn't specify capital letters in the beginning; in any case, by his use of grep, I was hoping he's comfortable enough with regex to use one more fine-tuned to his needs. –  Joseph R. Nov 7 '12 at 20:59
3  
I wasn't saying that to imply that you were wrong, but as a clarification for people who don't parse PCRE with wetware. –  bahamat Nov 7 '12 at 22:13
4  
Note that this option is GNU specific and will not work on several implementations of grep. Using sed is the only portable way I know how to do this. –  rahmu Nov 7 '12 at 22:59
1  
Or, even more elegantly, perl -e 'print "$_\n" for map {m/(\w*[A-Z]+\w*)/g} <>' yourfile.txt –  Joseph R. Nov 7 '12 at 23:20

The POSIX Basic Regular expression standard (used by default in grep, vim, less, sed, etc.) uses \< and \> to signify word boundaries. This allows a letter to follow white-space, as well as non-alphanumeric characters like quotes, dashes, equal-signs, etc. Use the -o option to print each match on a new line, et voila:

grep -o '\<[A-Z][a-z]*\>' yourfile.txt

Again, you might need to have change the regexp to suit your needs. Maybe by allowing numbers or a second capital letter..? This does both..

grep -o '\<[A-Z][a-z0-9]*[A-Z][a-z0-9]*\>' yourfile.txt
share|improve this answer
    
Good one, thanks for the explanation on \< and \>! –  delh Nov 9 '12 at 0:45
    
No, \< is not in the POSIX spec of BREs. The link you provide is not to that spec but to some man page of some version of GNU grep. –  Stéphane Chazelas Feb 7 at 16:26

you could use sed to only return the string and not the whole line

sed 's/.*\([A-Z]*\).*/\1/g' <file>

or

sed 's/[a-z]*\| //g' <file>
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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