LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-17-2018, 03:05 AM   #1
masavini
Member
 
Registered: Jun 2008
Posts: 285

Rep: Reputation: 6
grep for a string with both letters and digits...


hi,
is there a way to grep for a 'word' containing at least 1 letter and 1 digit (in any order)?
i mean something like this:
Code:
$ grep -iwo 'some_regex' <<< "this sample string n. 1: bu2bu"
bu2bu
i know this could be done with 3 separated grep commands:
Code:
$ grep -iwo '[^ ]\+' <<<"this sample string n. 1: bu2bu" \
| grep -i '[a-z]' \
| grep '[0-9]'
bu2bu
but i was wondering if it exists such a regex to perform this filtering with a single command...

Last edited by masavini; 12-17-2018 at 03:14 AM.
 
Old 12-17-2018, 03:14 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Perhaps:
Code:
egrep '([0-9][a-z]|[a-z][0-9])'
 
1 members found this post helpful.
Old 12-17-2018, 03:26 AM   #3
masavini
Member
 
Registered: Jun 2008
Posts: 285

Original Poster
Rep: Reputation: 6
Quote:
Originally Posted by NevemTeve View Post
Perhaps:
Code:
egrep '([0-9][a-z]|[a-z][0-9])'
much easier than i expected, thanks!

Code:
$ grep -Eio '[^ ]*([0-9][a-z]|[a-z][0-9])[^ ]*' <<< "this sample string n. 1: bu2bu"
bu2bu
 
Old 12-17-2018, 05:05 AM   #4
l0f4r0
Member
 
Registered: Jul 2018
Location: Paris
Distribution: Debian
Posts: 900

Rep: Reputation: 290Reputation: 290Reputation: 290
^ Beware of what you call "word". Generally, in the regex world, a word is composed of characters [A-Za-z0-9_] but you seem to consider that a word is everything except space character.
So with your last regex, "5apples.3strawberries" and "1A|3B" and "1r,3d" are only one-word matches. Some people would have considered them being 2-word matches.
Moreover, as a side-effect, you include final punctuation signs inside your matches (for example: "t3st." matches inside "this is a t3st.", not just "t3st")

Depending on what you want, you may keep your regex or use one of the suggestions below:
Code:
grep -Eo '[[:alnum:]_]*(([[:digit:]][[:alpha:]])|([[:alpha:]][[:digit:]]))[[:alnum:]_]*'
grep -Eo '\w*(([[:digit:]][[:alpha:]])|([[:alpha:]][[:digit:]]))\w*'

Last edited by l0f4r0; 12-17-2018 at 05:20 AM.
 
Old 12-17-2018, 05:40 AM   #5
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,126

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
Much simpler (and more readable) to use a more appropriate tool. awk for example is usually a better fit for field (i.e. "word") based processing.
And the regex handling is more flexible - use of logical AND for example.
 
Old 12-17-2018, 07:21 AM   #6
l0f4r0
Member
 
Registered: Jul 2018
Location: Paris
Distribution: Debian
Posts: 900

Rep: Reputation: 290Reputation: 290Reputation: 290
^ Sir, at your command! Here is a suggestion with awk
Code:
... | awk 'BEGIN{FS="[^A-Za-z0-9_]"} {for(i=1;i<=NF;i++) {if($i ~ /([[:digit:]][[:alpha:]])|([[:alpha:]][[:digit:]])/) {print $i} } }'
 
Old 12-17-2018, 02:20 PM   #7
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Taking the lovely solution of NevemTeve in post #2 and recasting it in awk ...

With this InFile ...
Code:
aaabbb   toss this
cccggg   toss this one too
q3rrst   keep this
99wxyz   keep this
kkll88   keep this
122333   another toss
... this awk ...
Code:
awk '{if (match($0,/([0-9][a-z]|[a-z][0-9])/)) print}' $InFile >$OutFile
... produced this OutFile ...
Code:
q3rrst   keep this
99wxyz   keep this
kkll88   keep this
Daniel B. Martin

.
 
Old 12-17-2018, 04:32 PM   #8
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,126

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
The OP only wants the matching "word", not the entire record. I was thinking more along the lines of ...
Code:
awk '{for (i=1; i<=NF; i++) {if ($i ~ /[0-9]/ && $i ~ /[[:alpha:]]/) {print $i}}}'
To me, Much more readable. Probably should use [:digit:] ... :shrug:
 
Old 12-17-2018, 10:14 PM   #9
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Quote:
Originally Posted by syg00 View Post
The OP only wants the matching "word", not the entire record. ...
With this InFile ...
Code:
Four4 score and se7ven 777 years ago our fath22ers brought forth
on this continent a 88new nation, conceived in liberty,
and 99dedicated to the proposition99 that all men are cre5ated equal.
... this awk ...
Code:
awk 'BEGIN{RS=" |\n"}
  {if (match($0,/([0-9][a-z]|[a-z][0-9])/)) print}' $InFile >$OutFile
... produced this OutFile ...
Code:
Four4
se7ven
fath22ers
88new
99dedicated
proposition99
cre5ated
Daniel B. Martin

.

Last edited by danielbmartin; 12-17-2018 at 10:26 PM. Reason: Tighten the code, slightly.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
to grep 100 letters out of 500 letters on certain criteria l_ravi69 Programming 3 10-13-2013 11:37 AM
[SOLVED] Bash Shell Script to check if a string has only alphabets and digits. aswani Programming 8 08-16-2012 09:49 AM
how to check if all letters of one string are in another string cliffyao Programming 4 11-12-2010 10:41 AM
BASH - convert single digits to double digits. rickenbacherus Programming 7 05-07-2008 06:53 AM
grep and digits gawain Linux - Software 7 02-20-2008 02:13 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:34 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration