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.

Suppose I have a file like this:

adasfddfd09
dsassd90897
323sdsdsdsd
sdddsdf56
dfdf45fdfdf

I want to search only those strings which have last two characters numeric with sed, grep and awk.

share|improve this question
3  
grep '[0-9][0-9]$' –  Stéphane Chazelas Jun 24 at 14:40
1  
I think the edit was wrong, since he has a file with one line, a string with multiple strings. –  polym Jun 24 at 14:41
    
do you only want it to end with two numbers or EXACTLY with two numbers and not more? –  polym Jun 24 at 14:48
1  
@polym, only user130240 can tell us, but if you look at the question as he posted it, I strongly suspect those are meant to be one per line. –  Stéphane Chazelas Jun 24 at 15:58
    
ah ok, thank you –  polym Jun 24 at 16:27

2 Answers 2

Commands for grep and sed

It looks like the original question was formatted incorrectly. Hence, the simplest grep and sed commands are:

egrep '[0-9]{2}$' /path/to/file

and

sed -rn '/[0-9]{2}$/p' /path/to/file

I'll leave the explanations below, which include information on these commands, but also work with multiple strings on single lines. They will still work, but include additional, potentially extraneous code.


Grep

grep '[^ ]*[0-9]\{2\}( |$)' /path/to/file

Explanation

  • [^ ]* Match any number of non-space characters.
  • [0-9]\{2\} Match two digits. (You could use [0-9][0-9] instead.)
  • ( |$) The digits should be the end of a "word", hence should be followed by either a space or an end-of-line terminator.

I prefer using extended grep instead, as you won't need to escape the curly braces. Hence,

grep -E '[^ ]*[0-9]{2}( |$)' /path/to/file

or

egrep '[^ ]*[0-9]{2}( |$)' /path/to/file

The question has been edited, but if there are multiple matches on a line, and you want to only output the matches, then use the -o flag. i.e.

egrep -o '[^ ]*[0-9]{2}( |$)' /path/to/file

Sed

</path/to/file tr ' ' '\n' | sed -rn '/[0-9]{2}$/p'

Explanation

  • </path/to/file tr ' ' '\n' Input file and change all spaces to newlines.
  • sed -rn Use extended regular expressions (similar to above) with -r, and don't print all the output immediately with -n.
  • [0-9]{2}$ This regular expression is similar to the one above in the grep line. However, since we've already removed all the spaces, we don't need to define the non-space characters at the beginning, nor the possible space at the end.
  • /<regex>/p Print out the lines matching <regex>.
share|improve this answer
    
Also matches dsassd90897 and only highlights matches, since its grep. –  polym Jun 24 at 14:42
1  
@polym, I think they want dsassd90897, right? Also, I'm not sure what output they want... and there's since been an edit to the question. Anyway, I've edited for the last part. –  Sparhawk Jun 24 at 14:43
    
yeah might be. it's a bit unclear. Nice answer though with egrep :) –  polym Jun 24 at 14:57
1  
This is wrong: [ $] -- that looks for a character that is either a space or a dollar sign. You were thinking of ( |$) –  glenn jackman Jun 24 at 15:10
    
@glennjackman Ah yes, thank you. Edited. –  Sparhawk Jun 24 at 15:13

sed plus awk should do the trick!

sed 's/ /\n/g' file1 | awk '/[0-9][0-9]$/'

If your file contains these strings line by line awk only should do the trick!

awk '/[0-9][0-9]$/' file1

If you want to match strings that end with EXACTLY two numbers and not more, then use these commands instead:

sed 's/ /\n/g' file1 | awk '/[^0-9][0-9][0-9]$/'

and

awk '/[^0-9][0-9][0-9]$/' file1

Output:

adasfddfd09
dsassd90897
sdddsdf56 

Explanation

  • sed splits your input string into multiple strings.
  • awk matches all strings that end with exactly two numbers.
share|improve this answer
1  
Nice edit (I think, but again the question is unclear :). +1 (For the sed part, I think you could do that in awk? I'm also not sure if tr would be faster, but probably only marginal if anything.) –  Sparhawk Jun 24 at 15:01
1  
Ha… I was curious, so I did a test. time for i in $(seq 1000000); do echo 'adasfddfd09 dsassd90897 323sdsdsdsd sdddsdf56 dfdf45fdfdf'; done | sed 's/ /\n/g' > /dev/null vs. time for i in $(seq 1000000); do echo 'adasfddfd09 dsassd90897 323sdsdsdsd sdddsdf56 dfdf45fdfdf'; done | tr ' ' '\n' > /dev/null On my computer, the variation between runs for either command is much higher than the difference between the two commands. –  Sparhawk Jun 24 at 15:07
    
it would be nice if awk splits and matches in one line, but I can't find any solution. :(. Is there any test if tr or sed is faster? EDIT: Ha, two guys, same thought! –  polym Jun 24 at 15:07
    
I always thought that the regex part of sed would be slower (and unnecessary here), but obviously I was wrong. –  Sparhawk Jun 24 at 15:08
    
yeah i tested it on my system with your commands, too :). sed seems to be faster :D –  polym Jun 24 at 15:10

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.