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
  • If any of the answers solved your problem, please accept it by clicking the checkmark next to it. Thank you! – Jeff Schaller Sep 2 '18 at 11:43
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:]]'

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.