2

I have looked through a number of question but they do not satisfactorily reply to my question.

I need to print words that match the pattern exactly not the lines containing that word. For example:

I am going home. Home is where heart is.

So when I search with pattern "home", I should get

home Home

I understand that grep -o will make my task easier, but my grep does not support that option. So I need some other solution.

Also I need an exact match. So that if there is a word homeless it should not be picked in selection.

2

Playing with perl :

$ echo 'I am going home. Home is where heart is.' | 
    perl -lne 'for (split /\W+/) {print $& if /\bhome\b/i}'

And even shorter, adapted from Joseph R. comment bellow (thanks to him)

$ echo 'I am going home. Home is where heart is.' | 
    perl -lne 'print $& while /\bhome\b/ig'

Result:

home
Home
| improve this answer | |
  • Even easier: perl -lne 'print $1 while /\b(home)\b/ig' – Joseph R. Nov 5 '14 at 17:51
  • 1
    Even shorter, see my edited post ;) – Gilles Quenot Nov 5 '14 at 18:05
  • That's why I like Perl that much, concision is great with this programming language ! – Gilles Quenot Nov 5 '14 at 21:22
  • not working for this I am going home. home,shelter,home is where heart is. output is only 2 home – Hackaholic Nov 7 '14 at 3:46
  • Concision? tr | grep is shorter! @Hackaholic Use \W+ instead of \s+ as the word separator. – Gilles 'SO- stop being evil' Nov 7 '14 at 4:17
0

using awk:

echo "I am going home. Home is where heart is. I dont like Homework." | awk '{for(i=1;i<=NF;i++) {gsub(/[^a-zA-Z0-9]/,"",$i); if(match(tolower($i),/^(home)$/))print $i;}}'

output:

home.
Home
| improve this answer | |
  • I think you used home or Home for pattern matching. I want to use just home and still get the desired output. – haldar55 Nov 5 '14 at 5:04
  • yep you need something else?? – Hackaholic Nov 5 '14 at 5:05
  • now check the code. i have edited for what you wanted – Hackaholic Nov 5 '14 at 5:07
  • 1
    This option is also picking the words which have "home" inside it like "homeless" or "homework" – haldar55 Nov 5 '14 at 12:16
  • @haldar55 edited the code as per your requirement – Hackaholic Nov 5 '14 at 15:02
0

Using awk to look for whole words similar to grep -o -w:

$ echo "I am going home. Home is where heart is." | awk -v 'RS=[^[:alnum:]_]' -v w="home" 'tolower($0)==w'
home
Home

As Gilles points out, this requires an awk, such as GNU awk, which supports regular expressions for RS.

| improve this answer | |
  • That's good, except that support for RS being a regular expression is not a standard feature. A system where the shell is ksh and grep isn't GNU or BSD grep is likely to have an awk that doesn't go much beyond POSIX. – Gilles 'SO- stop being evil' Nov 6 '14 at 22:52
0

You can use tr to normalize word separators, then grep to print matching words (with the options -Fx to match a string exactly and -i for case insensitivity).

tr -cs A-Za-z \\n | grep -Fxi home

If you're in a non-ASCII locale, note that many implementations of tr operate on bytes, not characters. Use another tool such as sed to perform the word separator normalization.

sed 's/[^[:alpha:]][^[:alpha:]]*/\n/g' | grep -Fxi home

All the commands in this answer are POSIX standard.

| improve this answer | |
-1
printf %s\\n 'I am going home. Home is where the heart is.' | 
sed 's/\([hH]ome\)*.\{,1\}/\1/g'

OUTPUT

homeHome

| improve this answer | |
  • he want to search for home and Home only using home. in your code you have added capital H – Hackaholic Nov 5 '14 at 5:09
  • But that's not the question - he says he wants to match a pattern. home is a pattern with one possible match - which is home. In other words, it is an instance. – mikeserv Nov 5 '14 at 5:13
  • My mistake, in case I wasn't clear, I wanted "home" to be matched to any way the word "Home" comes into picture i.e the checking should be case insensitive. – haldar55 Nov 5 '14 at 5:17
  • @haldar55 - in that case you need to filter the pattern first, at least you do with any portable sed statement. tr makes an excellent filter for that. Or even sed - but tr is faster. – mikeserv Nov 5 '14 at 5:23
-1

You can iterate over words, grep the specified word and remove punctuation characters

$ s="I am going home. Home is where heart is." 
$ for w in $s; do echo $w; done | grep -Ei '(^|[[:punct:]]*)home([[:punct:]]*|$)' | tr -d '[[:punct:]]'
home
Home
| improve this answer | |
  • Why not use [^[:alpha:]] for “not a letter”? That's what it's for. You should disable globbing in case there are characters \[?* in the string. And since punctuation is supposed to separate words, you would need to put all punctuation characters in IFS. – Gilles 'SO- stop being evil' Nov 7 '14 at 4:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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