I have a very large list of hostnames from which I am trying to print the TLD (.com, .net, .info, etc.) of each host. The problem is that the hosts have their TLDs in different fields, so I can't tell cut or awk to statically print one field.

Some example hostnames:

examplehost.net                             # tld is 2nd field (period delimited)
subdomain.otherhost.com                      # tld is 3rd field
subdomain.othersubdomain.yetanotherhost.info   # tld is 4th field

As a little workaround, I've just been adding a space to the end of each host that way I can include it in my regex pattern and grep for it.

sed 's/$/ /g' listofhosts.txt | grep -Eo '\.[a-z]{1,10} '

I was curious if there is a more elegant way to accomplish this.

  • 2
    sed 's/ .*//; s/.*\.//' – Satō Katsura Jun 7 '17 at 15:39
  • 1
    awk -F. '{print $NF}' listofhosts.txt maybe? – steeldriver Jun 7 '17 at 15:56
  • If any of the current answers solved your problem, please indicate so using the checkmark. Thank you! – Jeff Schaller Jun 18 '17 at 17:13

If your listofhosts.txt file does not have comments at the end of it, then steeldriver's commented command is how I would do it. Tell awk to split the fields on periods, then print the value of the last field:

awk -F. '{print $NF}' listofhosts.txt

Resulting in:

|improve this answer|||||

With single grep (if PCRE supported):

grep -Po '.*\.\K[^.]+$' listofhosts.txt 
|improve this answer|||||
grep -oE '\.[^.]+$'

perl -lne 'print /(\.[^.\s]+)\s/'

sed 's/^[[:space:]]*[^[:space:]]\{1,\}\([.][^.[:space:]]\{1,\}\)[[:space:]]\{1,\}.*/\1/'
|improve this answer|||||

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.