script for checking IP's hostname from file - linux

I used for to file one contain the IP with hostname like the /ec/hosts
and the other contain the IP and counter try to print the ip if hostname not found and if is found print the hostname.
Script:
for i in `cat ip | awk '{print $2}'` ;do
var=`grep "$i" Server_ip` |
awk ' {if($var == "") print $i else print $1}';
done
File 1
localhost 127.0.0.1
test 10.0.0.1
test1 10.0.0.2
File 2
3 127.0.0.1
2 10.0.0.1
1 10.0.0.2
4 10.0.0.3
5 10.0.0.4
Desired output
localhost
test
test1
10.0.0.3
10.0.0.4

You can try this;
#!/bin/bash
for i in `cat ip | awk '{print $2}'` ;do
var=`awk -v ip=${i} '$2 == ip {print $1}' Server_ip`
if [ -z "$var" ]; then
echo $i
else
echo "$var"
fi
done
Eg;
user#host:/tmp/test$ cat Server_ip
localhost 127.0.0.1
test 10.0.0.1
test1 10.0.0.2
user#host:/tmp/test$ cat ip
3 127.0.0.1
2 10.0.0.1
1 10.0.0.2
4 10.0.0.3
5 10.0.0.4
user#host:/tmp/test$ ./test.sh
localhost
test
test1
10.0.0.3
10.0.0.4

Related

Unable to get uniq -c in while loop

I'm trying to sort a log file and get a total count of unique IP addresses and do something with the ones that appear > than n. this is my first command:
$ grep -B 1 "foobar" ip.log | grep "IP Address" > ip_count.log
which outputs:
IP Address : 133.55.39.56
IP Address : 116.243.70.151
IP Address : 117.46.13.194
IP Address : 115.179.82.10
IP Address : 13.123.2.123
IP Address : 13.123.2.123
IP Address : 13.123.2.123
IP Address : 13.123.2.123
IP Address : 13.123.2.123
IP Address : 13.123.2.123
IP Address : 13.123.2.123
IP Address : 13.123.2.123
IP Address : 13.123.2.123
IP Address : 33.123.2.123
IP Address : 33.123.2.123
IP Address : 33.123.2.123
IP Address : 33.123.2.123
IP Address : 33.123.2.123
IP Address : 33.123.2.123
if i do this I get a proper count:
$ awk '{print $4}' ip_count.log | uniq -c
1 133.55.39.56
1 116.243.70.151
1 117.46.13.194
1 115.179.82.10
9 13.123.2.123
6 33.123.2.123
but if I do this I don't:
$ while read -r line ; do c=$(echo $line | awk '{print $4}' | \
uniq -c | awk '{print $1}') ; if [[ $c -gt 1 ]]; then echo "$line" ; \
fi ; done < ip_count.log
1 133.55.39.56
1 116.243.70.151
1 117.46.13.194
1 115.179.82.10
1 13.123.2.123
1 13.123.2.123
1 13.123.2.123
1 13.123.2.123
1 13.123.2.123
1 13.123.2.123
1 13.123.2.123
1 13.123.2.123
1 13.123.2.123
1 33.123.2.123
1 33.123.2.123
1 33.123.2.123
1 33.123.2.123
1 33.123.2.123
1 33.123.2.123
i'm not sure what i'm doing wrong within the loop, so maybe someone could tell me. there's probably some better way to combine all this into one command anyway, so any tips would be appreciated, thanks.
It seems no loop is needed :
uniq -c ip_count.log | awk '$1 > 1 { print $1" "$5 }'
When you read the file in the loop, it executes command row by row.
awk '{print $4}' ip_count.log | uniq -c
In the above, all records are read from stdin and process.
when you execute loop while read -r line your variable $line only contains 1 record instead of the whole file.
You can do it in single awk command using an associative array.
An alternative solution using awk
$awk -F':' '{ count=1; a[$2]=a[$2]+count} END {for (i in a) if (a[i]>1 )print i, a[i]} ' ip_count.log
33.123.2.123 6
13.123.2.123 9
$
Explanation:
-F':' --> we are setting custom field seprator as :
count=1; --> Initialize a variable as default value 2
a[$2]=a[$2]+count --> Create a associative array with $2 as index and count as values.
END --> Wait till { } code block execution is complete
{for (i in a) if (a[i]>1 )print i, a[i]} --> Loop through each value in array
Also, it's a good practice to pass sorted input to uniq command.
For example:
$echo -e "a\na\nb\na"
a
a
b
a
$echo -e "a\na\nb\na" | uniq -c
2 a
1 b
1 a
$echo -e "a\na\nb\na" | sort | uniq -c
3 a
1 b
$

Set an awk,sed output to a variable in Bash

UPDATE:
Now I have a simpler file to handle, similar to this:
127.0.0.1 25 127.0.0.1
127.0.0.1 25 127.0.0.1
127.0.0.1 32828 127.0.0.1
127.0.0.1 32830 127.0.0.1
127.0.0.1 32906 127.0.0.1
127.0.0.1 32908 127.0.0.1
127.0.0.1 32984 127.0.0.1
(first column ip_local, second column port_local and last column ip_foreign)
All I have to do is to send the awk output to a variable.
The code I managed to write is this, but I still have problems to process the text file...
#!/bin/sh
for i in `cat DEV0_IPsListSep.txt`;
do
ip_local=$(awk '{print $1}' $i);
port_local=$(awk '{print $2}' $i);
ip_foreign=$(awk '{print $3}' $i);
if [$port_local < 3200] || [$ip_foreign != 127.0.0.1] || [$ip_foreign !=
192.168.1.1]
then
echo $ip_foreign >> IPFinalList.txt;
fi
done
I have a bash script that processes a file with two columns. The first column is the local ip addresses, the other is the one of the foreign addresses.
Example:
127.0.0.1:25 127.0.0.1:33862
127.0.0.1:25 127.0.0.1:36498
127.0.0.1:25 127.0.0.1:37338
127.0.0.1:25 127.0.0.1:37410
127.0.0.1:25 127.0.0.1:38320
127.0.0.1:25 127.0.0.1:39428
127.0.0.1:25 127.0.0.1:39514
127.0.0.1:25 127.0.0.1:39768
127.0.0.1:25 127.0.0.1:39846
127.0.0.1:25 127.0.0.1:40376
I would like the script to assign the outputs of sed and awk commands to my custom variables, to separate IPs and ports.
I tried to create a script but still receive syntax errors...
#!/bin/sh
for i in `IPslist.txt`;
ipLocal=$(awk '{print $1}' | sed -e 's/:.*//' $i)
portLocal=$(awk '{print $1}' | sed -e 's/.*://' $i)
ipForeign=$(awk '{print $2}' | sed -e 's/:.*//' $i)
portForeign=$(awk '{print $2}' | sed -e 's/.*://' $i)
if [ $portLocal < 3200 ] || [ $ipForeign != 127.0.0.1 ] || [
$ipForeign != 192.168.1.1 ]
then
echo $ipForeign >> IPFinalList.txt
fi
With single awk process (optimized solution):
awk -F':|[[:space:]]+' '$2<3200 || $3!= 127.0.0.1 || $3!= 192.168.1.1' IPslist.txt > IPFinalList.txt

Shell Script: Get eth name from Subnet mask

My machine has multiple ethernet device such as eth0, eth1, etc. One of those IP will have an IP in the range 192.168.x.x. How can I fetch the device name using shell script? (Preferably using ip commands rather than ifconfig)
Like
eth0 192.168.2.3
or
eth3 192.168.5.6
you can try this;
ip -o -4 a | awk '$2 ~ "eth" { gsub(/\/.*/, "", $4); print $2" "$4}'
to all interfaces;
ip -o -4 a | awk ' { gsub(/\/.*/, "", $4); print $2" "$4}'
eg:
user#host:/tmp/$ ip -o -4 a | awk ' { gsub(/\/.*/, "", $4); print $2" "$4}'
lo 127.0.0.1
eth0 x.x.x.x
docker0 x.x.x.x
user#host:/tmp/$ ip -o -4 a | awk '$2 ~ "eth" { gsub(/\/.*/, "", $4); print $2" "$4}'
eth0 x.x.x.x
man ip said :
-o, -oneline
output each record on a single line, replacing line feeds with the '\' character. This is convenient when you want to
count records with wc(1) or to grep(1) the output.
-4 a : Only show TCP/IP IPv4

How to find out your IP addresses using bash

I have a server that has several ip addresses. I want to work out their exact values in bash. I am looking for something like:
a=returnIpAddressStartingWith 10.60.12
b=returnIpAddressStartingWith 10.60.13
so that the following returns:
> echo $a
10.60.12.23
Is there a reasonable way of doing this on linux?
You can use a function like this for searching:
findip() {
ip -4 addr | awk -v ip="$1" -F '[/[:blank:]]+' '$2 == "inet" && index($3, ip){print $3}'
}
And find the IP by:
a=$(findip '10.60.12')
Parse it out of the 'ip addr show' list using grep/awk/cut, then optionally, if you need to access it as an array, copy your list into a Bash array:
# Create a string that is the list of all variables
IPSTR=`ip addr show | fgrep 'inet ' | fgrep -v '127.0.0.1' | awk '{ print $2 }' | cut -d '/' -f 1`
I=0
for IP in $IPSTR ; do
IPARY[$I]=$IP
I=$(($I+1))
done
echo "First IP in array is ${IPARY[0]}"
echo "Number of IP addresses in array is ${#IPARY[*]}"

How to place the output of an echo statement and an arp statement on one line?

How can I get the output "echo" and "macaddress" on one line?
This is what I've got:
ipRange="192.168.0."
macaddress= arp | grep -w "$ipRange$1" | awk '{print $3,$1}'
ping -c1 "$ipRange$1" > /dev/null
if [ $? -eq 0 ]; then
echo "deze host met mac address en ip address is up $macaddress"
else
echo "het is down"
fi
This is the output:
VirtualBox ~ $ bash test2.sh 149
e0:b9:a5:f8:24:c3 192.168.0.149
deze host met mac address en ip address is up
this should do output in single line
ipRange="192.168.0."
macaddress=$(arp | grep -w "$ipRange$1" | awk '{print $3,$1}')
ping -c1 "$ipRange$1" > /dev/null
if [ $? -eq 0 ]; then
echo "deze host met mac address en ip address is up $macaddress"
else
echo "het is down"
fi
Just replace macaddress= arp | grep -w "$ipRange$1" | awk '{print $3,$1}'
with macaddress=$(arp | grep -w "$ipRange$1" | awk '{print $3,$1}')

Resources