1

I have some lines in a file like:

This is one word1:word2 of the lines    
This is another word3:word4 of the lines    
Line without a match    
Yet another line word5:word6 for test

I need to grep for : and to return words just before and after :.

Output I need from greping above lines is

word1:word2
word3:word4
word5:word6
1

With GNU grep:

start cmd:> echo "This is one word1:word2 of the lines" |
  grep -Eo '[[:alnum:]]+:[[:alnum:]]+'
word1:word2

start cmd:> echo "This is one wordx:wordy of the lines" |
  grep -Eo '[[:alpha:]]*:[[:alpha:]]*'
wordx:wordy

start cmd:> echo "This is one wo_rdx:wo_rdy of the lines" |
  grep -Eo '[[:alpha:]_]*:[[:alpha:]_]*'
wo_rdx:wo_rdy
  • This works great for alpha numeric words. Please advice the case of underscores also. I mean the words can be like word_one_alpha word_two_beta etc. Thanks a lot for the quick help. – Mr. B Nov 25 '14 at 9:54
1

POSIXly (though beware some tr implementations (like GNU's) don't work properly with multi-byte characters).

tr -s '[:space:]_' '[\n*]' << 'EOF' |
  grep -xE '[[:alnum:]_]+:[[:alnum:]_]+'
This is one word1:word2 of the lines and another is word:word   
This is another word3:word4 of the lines  and this is not wordnot::wordnot
Line without a match    
Yet another line word5:word6 for test
This is one wo_rdx:wo_rdy of the lines
This is one wordx:wordy of the lines
not/a:match
EOF

Gives:

word1:word2
word:word
word3:word4
word5:word6
rdx:wo
wordx:wordy
1

For all case of your desired result, you can use GNU grep with PCRE support(-P) and its word regex (\w) as following:

grep -oP '\w+:\w+' file

Input file:

This is one word1:word2 of the lines and another is word:word   
This is another word3:word4 of the lines  and this is not wordnot::wordnot
Line without a match    
Yet another line word5:word6 for test
This is one wo_rdx:wo_rdy of the lines
This is one wordx:wordy of the lines

Output:

word1:word2
word:word
word3:word4
word5:word6
wo_rdx:wo_rdy
wordx:wordy

As you can see grep doesn't match wordnot::wordnot pattern, because it has a extra : between itself.

  • you don't need to go for character class. Just grep -oP '\w+:\w+' file would be fine. – Avinash Raj Nov 25 '14 at 12:13
0

If you were to use sed to do this thing, it might be done like:

sed -n 's/\( *: *\)*\([^ ]*:[^ ]* *\)*.\{,1\}/\2/g;/./p' <<\IN 
This is one word1:word2 of the lines
This is another word3:word4 of the lines
Line without :a :match
Yet another line word5:word6 for test:123:test
IN

OUTPUT

word1:word2 
word3:word4 
word5:word6 test:123:test
0

Through grep,

grep -oP '[^:\s]+:[^:\s]+' file

OR

grep -oP '\S+?:\S+' file

The above command not only fetches the strings like foo:bar but also ?foo:bar?

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.