2

I have a text file on a Linux machine which contains the strings:

appset.org 87.76.29.21 ns1.appset.org ns2.appset.org
bbchannel.eu 87.77.29.25 ns1.appset.org ns2.appset.org
cyberset.it 87.76.29.22 ns1.appset.org ns2.appset.org
cybersetsystems.com 87.76.29.21 ns1.appset.org ns2.appset.org
romelidays.com 87.98.29.21 ns1.appset.org ns2.appset.org
novaprospect.eu 87.76.29.21 ns1.appset.org ns2.appset.org

All I want is to remove the part starting from the IP address and get output with only website name eg appset.org,bbchannel.eu.

The code I have tried is:

 #!/bin/bash
  while read p; do
      echo "$p" | cut -c 1-13
   done <experiment

But it doesn't seem to be right. I have also tried using the sed command but still my logic doesn't work. I am really new to bash. Any help would be really appreciated.

terdon
  • 242,166

1 Answers1

6

You got the right tool for the job, cut, but are making it far more complicated than you need. There is absolutely no reason to use a bash loop here, that just makes things slower and more complicated. cut will process every line in the file by itself. However, the default delimiter for cut is a tab, not a space, so you need to tell it to cut on spaces using the -d flag. Then, instead of telling it to cut specific characters, just tell it to print the first field with -f 1:

$ cut -d' ' -f 1 file 
appset.org
bbchannel.eu
cyberset.it
cybersetsystems.com
romelidays.com
novaprospect.eu

With sed, you would try to remove everything after the first space:

$ sed 's/ .*//' file 
appset.org
bbchannel.eu
cyberset.it
cybersetsystems.com
romelidays.com
novaprospect.eu

Or, you could use awk which splits into fields on whitespace by default:

$ awk '{print $1}' file 
appset.org
bbchannel.eu
cyberset.it
cybersetsystems.com
romelidays.com
novaprospect.eu

Or perl:

$ perl -pe 's/\s.*//' file 
appset.org
bbchannel.eu
cyberset.it
cybersetsystems.com
romelidays.com
novaprospect.eu

Or perl again:

$ perl -lane 'print $F[0]' file 
appset.org
bbchannel.eu
cyberset.it
cybersetsystems.com
romelidays.com
novaprospect.eu

You could even do it in the shell, but this will be far slower for larger files and is generally not a good idea:

$ while read want rest; do echo "$want"; done < file
appset.org
bbchannel.eu
cyberset.it
cybersetsystems.com
romelidays.com
novaprospect.eu

Or, safer for arbitrary input:

$ while read -r want rest; do printf '%s\n' "$want"; done < file
appset.org
bbchannel.eu
cyberset.it
cybersetsystems.com
romelidays.com
novaprospect.eu
terdon
  • 242,166
  • With the while read part, you'll also want to make sure $IFS contains the characters you want to consider as delimiter. – Stéphane Chazelas Nov 01 '20 at 14:23
  • @terdon Thank you so much – Avinash Babu Nov 01 '20 at 14:25
  • @terdon ..Let me as you one more thing..How can i do this by only making change to the first line of the text.. ie 'appset.org 87.76.29.21 ns1.appset.org ns2.appset.org'. Do i have to use a loop in this case ? – Avinash Babu Nov 01 '20 at 14:37
  • @StéphaneChazelas yes, but since here the delimiter is (apparently) supposed to be a space, there didn't seem to be any reason to set it explicitly. – terdon Nov 01 '20 at 14:47
  • 1
    @AvinashBabu no, but that is a completely different question. The simplest way would be to use head -n1 to print only the first line and pipe that to cut like this: head -n1 file | cut -d' ' -f1. – terdon Nov 01 '20 at 14:48