Reading the text file for particular format

Hi All,

Need your help!!

I have particular host file with below format:

172.34.45.67      Host1 Host2
134.45.56.67      Host3 Host4 Host5

I need shell script snippet which read this file and change the format of the file to the below format

172.34.45.67      Host1
172.34.45.67      Host2
134.45.56.67      Host3 
134.45.56.67      Host4
134.45.56.67      Host5

Thanks in advance

awk '{for(i=2;i<=NF;i++)print $1,$i}' file
1 Like

Thanks JODA for the prompt reply, It is working and priniting on the console. I want to change the same thing in the file. It is not changing that thing in the input file.

And one more thing, if am passing "file" alone at the end of the awk file itis throwing error and than I pass it as $file in the awk command

awk '{for(i=2;i<=NF;i++)print $1,$i}' $file

it is working and printing on the console but not changing in the file

Could you please suggest for this solution also?

Thansk in advance.

Have you stored file name in variable file?

Awk does not change the input file. You have to redirect the output to another file and rename it

awk '{for(i=2;i<=NF;i++)print $1,$i}' $file > temp
mv temp $file
1 Like

Thanks Anbu

It is working for me thanks a lot.

---------- Post updated at 06:56 AM ---------- Previous update was at 06:37 AM ----------

Hi One more question:- Need a best solution fit to read the line by line and store each value in the variables and use that variables to ping thee ip and host name for e.g:-

172.34.45.67      Host1
172.34.45.67      Host2
134.45.56.67      Host3 
134.45.56.67      Host4
134.45.56.67      Host5

Storing each ip in one $ip variable and host name into $host
Implemented below solution :-

counter=0
typeset -a Server
while IFS=" " read name ip; do
Server[counter].name=$name
Server[counter].ip=$ip

any straight forward solution for this?

If you simply want to ping the IP & host name. Then no need to store them in array, just read and ping:

while read ip host
do
        # ping $ip
        # ping $host
done < file

But if you want to use these values later by storing them in an array:

typeset -a HOST
typeset -a IP
typeset -i idx

while read ip host
do
        (( idx++ ))
        HOST[$idx]="$host"
        IP[$idx]="$ip"
done < file
1 Like

Thanks Yoda,

Am storing that IP and host for future purpose to use it to compare them.
I applied that above mentioned logic but it is giving me error

 
"[: -lt: unary operator expected" 

code snippet of my script

 
while read ip host
do
(( idx++ ))
HOST[$idx]="$host"
IP[$idx]="$ip"
if [ $(ping -q -c 1 -t 1 "$host" |grep PING | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') = "$ip" ]

At below line it is giving me above error

 
if [ $(ping -q -c 1 -t 1 "$host" |grep PING | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') = "$ip" ]

I don't see -lt operator anywhere in the code fragment that you posted!

I guess you did not post the complete code. By the way you can set xtrace/verbose and run your code to check what exactly is causing the error:

#!/bin/bash -xv

Hi Yoda

Below is the shell script

 
#! /bin/bash
cat "./Myfile" > input
file="input"
sed -i".backup" 's/^#.*$//' $file
sed -i '/^[[:space:]]*$/d' $file
awk '{for(i=2;i<=NF;i++)print $1,$i}' $file  > temp
mv temp $file
while read ip host
do
(( idx++ ))
HOST[$idx]="$host"
IP[$idx]="$ip"
if [ $(ping -q -c 1 -t 1 "$host" |grep PING | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') = "$ip" ]
 then 
  echo "$name PINGS">>pingresults.txt
  else 
  echo "$name doesnot PINGS">>pingresults.txt
 fi
   
done < $file

At line 9 , am getting the

"[: -lt: unary operator expected"

error for operator which is the if statement and matching the ip with the ping statement output

line 9 is

 
if [ $(ping -q -c 1 -t 1 "$host" |grep PING | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') = "$ip" ]

if [ "$(ping -q -c 1 -t 1 "$host" |grep PING | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')" = "$ip" ]
1 Like