0

I have a file with content similar to:

mail.google.com
srv1.mail.google.com
google.com
facebook.com
yahoo.com
tt.twitter.com

I want to search for lines with subdomains. I used this command:

grep -e '(.\.)*.\..$' test.txt

The command details:

  • (.\.)* : for any characters followed by dot one or more times.
  • .\..$ : anycharacter followed by dot, then any character

Examples of the string patterns I expect to find:

mail.google.com
srv1.mail.google.com

but it does not find anything. The output I am looking for should be lines with subdomains:

mail.google.com
srv1.mail.google.com
tt.twitter.com
1
  • If any of the answers solved your problem, please accept it by clicking the checkmark next to it. Thank you!
    – Jeff Schaller
    Sep 2, 2018 at 11:43

2 Answers 2

2

Try the following:

grep -E '(.+\.)+.+\..+$' test.txt

Output:

mail.google.com
srv1.mail.google.com
tt.twitter.com

Details:

  • (.+\.)+ - any characters followed by dot, search for this grouping one or more times.
  • .+\. - any character one or more times followed by a single period.
  • .+$ - any character one or more times, followed by an end-of-line.

The problem with your regular expression is/are:

  • (.\.)* - matches any character, and then a period. But the * may match zero or more times. You probably want +.
  • .\. - matches exactly one character, then a period. You want a + after the first . (.+) to match one or more characters.
  • .$ - matches exactly one character, then an end of line. You want a + after the . (.+) to match one or more characters.
0

If you're OK with simplifying the criteria to "lines that have at least two periods", you could use a simple grep:

grep -E '\.[^.]+\.' < file

This enables extended regular expressions then looks for a period followed by one-or-more non-periods followed by a period. You could tighten it down further by requiring some number of characters to appear on either side of the periods:

grep -E '.\.[^.]+\..' < file

The above would avoid false-positive hits on input like:

foo.com.

or .com.

Based on this Stack Overflow answer from 2014, a TLD cannot be all numeric, but could (in theory) be a single character, so you could use:

grep -E '\.[^.]+\.[[:alpha:]]'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .