0

I have a file called ips.txt and it has values like below:

cat ips.txt

abc.com.   10.120.20.4 10.120.20.5 ... # there can be many ips separated by a space
xyz.com.   10.120.20.6

I want to read this file line by line with a loop and do some other works.

And als I need to remove that . as well at the end of each domain name abc.com. and assign each ip to a variable (if it can be stored to an array, it is great)

So here's what I tried:

input="ips.txt"
while IFS= read -r line
do
  echo "$line"
  domain="" # need to assign abc.com
  ip_one= "" # need to assign the first ip occurence
  ip_two= "" # need to assign the second ip occurence
  ...
  ip_n= "" # need to assign the nth ip occurence

  # some other commands I need to execute with domain name and all the ips collected
done < "$input"

how can I assign the ip values to different variables? and use them? It is better if I can Store the IP's in a array like data type so it is more easier as I don't know how many IP's are there for some line in the ips.txt file.

Can someone help me do this?

  • If you can specify what you want to do with the ips you may get much better answers/advice. Arrays or variables should be the last resort. – perreal Oct 27 '20 at 17:27
  • I want to ping each of these `ip` addresses. – Jananath Jayarathna Oct 27 '20 at 17:51
  • `need to remove that . as well at the end of each domain name abc.com. ` → a domain name ends with a dot, this is the norm. If your implementation software does not support the end dot, then it is broken See: https://stackoverflow.com/questions/19480767 – Léa Gris Oct 27 '20 at 18:07

2 Answers2

0

Start with a standard array read. Assign to $@, use parameter expansion to strip the dot, then shift it off the stack, and you can assign back to your original array.

input="ips.txt"
declare -A lookup=()
while read -a ips # ips is an array
do set -- "${ips[@]}"  # assign the array to $@
   domain="${1%.}"     # assign abc.com without the dot
   shift               # dump the first column; now $@ is just the IP's
   for ip in "$@"; do lookup[$ip]="$domain"; done # assign the domain to each IP
done < "$input"

now

$: echo ${lookup[10.120.20.5]}
abc.com
Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
  • the `IFS=` looks strange, shouldn't it be `IFS=' '`? `set -- "${ips[@]}"` you may `unset ips[0]` in a similar fashion to `shift`. Or `ips=("${ips[@]:1}")` – KamilCuk Oct 27 '20 at 17:31
  • when I try to `echo $ips` it doesn't print any values. prints empty output – Jananath Jayarathna Oct 27 '20 at 17:49
  • And ` domain="${1%.}"` still prints domains with `.` at the end... i think this code is not properly working. – Jananath Jayarathna Oct 27 '20 at 17:51
  • I think I was briefly considering adding `.` to IFS but that would have broken a lot of things, and somehow it got left there. Apologies to all. – Paul Hodges Oct 27 '20 at 17:59
  • Would have been more educative to inform poster he is duplicating a question and flag the question as dupe. – Léa Gris Oct 27 '20 at 18:04
  • @PaulHodges now it works, but let's say we need to ping the each ip belongs to each domain how can I do that? I thought there should be another loop to do that. How can I do this with your answer – Jananath Jayarathna Oct 27 '20 at 18:07
0

Using set, and shift:

while IFS= read -r line; do       
  set $line                       
  domain=$(sed 's/\.$//' <<< "$1")                     
  shift                           
  for ip in $@; do                                    
    echo "domain: $domain ip: $ip"
  done                            
done < "$input"
perreal
  • 94,503
  • 21
  • 155
  • 181