Printing with multiple delimiters - linux

Im using this script
#!/bin/bash
echo Su direccion IP es:
/sbin/ifconfig | grep 'inet addr:' | cut -d: -f2 | awk '{print $1}'
which outputs a list of all of my ip addresses
but id like to add before each address the corresponding name
example
eth0: adresss1
tun0: address2
any advice? id be grateful for some explanation
i would also like to filter the lo connection if possible? thanks

Another awk:
ifconfig | awk -v OFS=": " -v RS= '$1!="lo" && split($0, a, /inet addr:/) > 1{
sub(/ .*/, "", a[2]); print $1, a[2]}'
eth0: 192.168.0.101
tun0: 10.1.111.123

ip -o addr list | awk -F'[[:space:]/]+' '$3 == "inet" && $2 != "lo" { print $2 ": " $4 }'

ip r show | awk '{print $3 $1}'

I think my take on it would be this:
$ ip addr |
awk '/^[0-9]+:/{print ""} 1' |
awk -vRS= '{for(i=1;i<NF;i++)if($i~/^inet/)print $2,$(i+1)}'
This uses two awk instances: the first splits records by adding blank lines, and the second to step through fields searching for addresses.
The output of this pipeline will contain one line per IP address (IPv6 included).
Note that in ifconfig notation, a second IP address on an interface might show up as a "sub-interface" like eth0:0. This notation is only useful in conjunction with ifconfig, which as you've seen in comments is not the recommended way to deal with modern linuces.

Related

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[*]}"

find ip address of my system for a particular interface with shell script (bash)

I am trying to find ip-address of my own system through a shell script and write into a text thats my script content
#!/bin/bash
wifiip=$(ip addr | grep inet | grep wlan0 | awk -F" " '{print $2}'| sed -e 's/\/.*$//')
eth0ip=$(ip addr | grep inet | grep eth0 | awk -F" " '{print $2}' | sed -e 's/\/.*$//')
if [ "$eth0ip" == "0" ]; then
echo "$eth0ip" | grep [0-9]$ > /home/pi/att/ip.txt
else
echo "$wifiip" | grep [0-9]$ > /home/pi/att/ip.txt
fi
and trying to do something like if one interface is not up print another ip in ip.txt
but it's giving
ip.sh: 14: [: unexpected operator
Let's clean up your code first. You don't need chains of a dozen different commands and pipes when you're already using awk. This:
wifiip=$(ip addr | grep inet | grep wlan0 | awk -F" " '{print $2}'| sed -e 's/\/.*$//')
can be written simply as this:
wifiip=$(ip addr | awk '/inet/ && /wlan0/{sub(/\/.*$/,"",$2); print $2}')
but your whole script can be written as just one awk command.
I need you to update your question with some sample output of the ip addr command, the output you want from the awk command given that input, and explain more clearly what you're trying to do in order to show you the correct way to write that but it might be something like this:
ip addr | awk '
/inet/ { ip[$NF] = $2; sub(/\/.*$/,"",ip[$NF]) }
END { print ( "eth0" in ip ? ip["eth0"] : ip["wlan0"] ) }
' > /home/pi/att/ip.txt
Here is a nice way to get your IP address. This gives you the address used to reach the internet at the test, so it will give you correct IP even if you change from Wifi to eth or to any other IF type.
See more detailed post here: Linux bash script to extract IP address
my_ip=$(ip route get 8.8.8.8 | awk '/8.8.8.8/ {print $NF}')
To get interface name:
my_if=$(ip route get 8.8.8.8 | awk '/dev/ {f=NR} f&&NR-1==f' RS=" ")

Bash script to get all IP addresses

I am trying to write a bash script to get all IP addresses on a server. The script should work on all major distros. Here is what I have:
ifconfig | grep 'inet addr:' | awk {'print $2'}
Resulting in:
addr:10.1.2.3
addr:50.1.2.3
addr:127.0.0.1
How can I first remove the addr: prefix? Second, how I can exclude 127.0.0.1?
ifconfig was obsoleted by ip. It also has the flag -o that write outputs easy to parse. Use ip -4 to show only IPV4 addresses. Note the simpler script, it already exclude the loopback address:
ip -o addr | awk '!/^[0-9]*: ?lo|link\/ether/ {print $2" "$4}'
Or if you don't want the networks:
ip -o addr | awk '!/^[0-9]*: ?lo|link\/ether/ {gsub("/", " "); print $2" "$4}'
There's no need for grep. Here's one way using awk:
List only addr:
ifconfig | awk -F "[: ]+" '/inet addr:/ { if ($4 != "127.0.0.1") print $4 }'
List device and addr:
ifconfig | awk -v RS="\n\n" '{ for (i=1; i<=NF; i++) if ($i == "inet" && $(i+1) ~ /^addr:/) address = substr($(i+1), 6); if (address != "127.0.0.1") printf "%s\t%s\n", $1, address }'
Simply using hostname you can get a list of all your IP addresses, using the -I flag.
i.e.
$ hostname --all-ip-addresses || hostname -I
10.10.85.100 10.20.85.100 10.30.85.100
whereas
$ hostname --ip-address || hostname -i
::1%1 127.0.0.1
Centos7 (k3.10.0)
This is merely a distillation of several prior answers and comments. Sample output is included.
To list IPs:
Using ip:
(Restricted to IPv4 and global)
$ /sbin/ip -4 -o addr show scope global | awk '{gsub(/\/.*/,"",$4); print $4}'
192.168.82.134
138.225.11.92
138.225.11.2
Using ifconfig:
(Excluding 127.0.0.1)
$ /sbin/ifconfig | awk -F "[: ]+" '/inet addr:/ { if ($4 != "127.0.0.1") print $4 }'
192.168.82.134
138.225.11.92
138.225.11.2
To map IPs to hostnames, see this answer.
Here is a similiar script for what I have tested to get an ip-range of addresses, but
it is slowly - somebody might give a hint, how to accelerate this ? (the ip-range here is an example for to get all lines, who seems to be up - between Vancouver and Korea) :
#!/bin/bash
for ip in {209..210}.{125..206}.{5..231}.{65..72}
# any ip between 209.126.230.71 and 210.205.6.66
do
printf ' === %s ===\n' "$ip"
whois "$ip" >> /home/$user/test001.txt
done
If this is too trivial or some mistake in it here, simply answer or comment.
This script would last until finish about 5 to 8 hours.
Use grep -v to ignore 127.0.0.1
ifconfig | grep 'inet addr:' | awk {'print $2'} | grep -v '127.0.0.1'
Use sed to edit out the 'addr:'
ifconfig | grep 'inet addr:' | awk {'print $2'} | grep -v '127.0.0.1' | sed -e 's/addr://'
ifconfig | grep 'inet addr:' | awk {'print $2'} | awk 'BEGIN{FS=":"}{print $2}' | grep -v '127.0.0.1'
if it is only the "addr:" word that you'd like to remove I would use sed instead of awk like
ifconfig | grep 'inet addr:' | awk {'print $2'}| grep -v 127.0.0.1 | sed -e 's/addr://'
It's a very tricky solution but it works:
ip a | awk ' !/[0-9]+\: lo/ && /^[0-9]\:/ || /inet / && !/127\.0\.0\.1/ {print $2}'
Output:
eth0:
192.168.0.1/24
Better yet:
ip a | awk ' !/[0-9]+\: lo/ && /^[0-9]\:/ || /inet / && !/127\.0\.0\.1/ {print $2}' | perl -i -pe "s/:\n/: /g;" -pe "s/\/[\d]+$//"
Output:
eth0: 192.168.0.1
I don't have a machine with several non loopback interfaces I can check it with, feel free to post your findings.
I'm always surprised to see people using sed and awk instead of perl.
But first, using both grep and awk with an extra option, feel free to just:
ifconfig | grep 'inet addr:' | awk {'print $2'} | awk -F: {'print $2'} | grep -v '127.0.0.1'
replacing the awks with perl:
ifconfig | grep 'inet addr:' | perl -F\\s\|: -ane 'print "$F[2]\n"' | grep -v '127.0.0.1'
replacing the greps within the same perl script:
ifconfig | perl -F\\s\|: -ane 'next if !/^inet addr:/ or /127\.0\.0\.1/; print "$F[2]\n"'
and lastly just using the power of perl's regex:
ifconfig | perl -ne 'next if !/inet addr:(?<ip>[0-9.]+)/ or $+{ip} == "127.0.0.1"; print "$+{ip}\n"'
I would to introduce you to a command-line tool called OSQuery by Facebook which helps you get system info by making SQL-like queries. For your case for instance, you would have enter;
osquery> select * from interface_addresses;
Which would output something like;
interface = wlan0
address = 192.168.0.101
mask = 255.255.255.0
broadcast = 192.168.0.255
point_to_point =
Which I find a lot more neat and convenient.
ifconfig | grep 'inet addr:' | awk {'print $2'} | cut -d ":" -f 2

Multiple Field separators with AWK

I'm trying to separate the ifconfig and give me the output just the current IP, broadcast, and netmask. The problem I'm running into is that the output is in spaces and in colons. I must be missing something, because I can't seem to get around this part. It doesn't seem that my OFS statement is working.
ifconfig eth0 | grep "inet addr" | awk -F ':' 'BEGIN{OFS=" ";}{print $2}'
Outputs this:
127.0.0.1 Bcast
The above is the IP of the unit. I really just want it to output
127.0.0.1
Some easy solutions:
ifconfig eth0 | tr : \ | awk '/inet addr/{ print $3 }'
and
ifconfig eth0 | tr -s \ | awk '/inet addr/{print $4 }' FS=':| '
also:
ifconfig eth0 | awk '/inet addr/{print $13 }' FS=':| '
If you know that you will always have a static string, then maybe just a substitution will work for you?
ifconfig eth0 | awk '/inet addr/{ sub(/addr:/, "", $2); print $2; }'
You can also use sed:
ifconfig eth0 | sed -n '/inet addr/{s/[^:]*:\([^ ]*\).*/\1/p}'

In BASH, Is there any way to find exactly the IP address for all interfaces? And remove all other information's?

How can i get only IP and which interface IP it is? So that i can keep a record file such as realtime.ini
1 - test.sh
#!/bin/bash
ipstring ='inet (.*)'
for i in $(ip addr);
do
echo $i #on found it write down to my realtime.ini as a list for future query
done
2 - realtime.ini
em1,192.168.1.2
lo,127.0.0.1
wlan0,<not found>
Follow up: Just for single ip:
$ ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'
192.168.1.2
This is not terribly elegant, nor is bash, but you can do the following if you have both awk and sed:
ifconfig | awk 'BEGIN { FS = "\n"; RS = "" } { print $1 $2 }' | sed -e 's/ .*inet addr:/,/' -e 's/ .*//'
I wouldn't bet on this being hugely portable either, so maybe someone has a better answer.
if you install moreutils package, you can use handy ifdata command:
for INTF_PATH in /sys/class/net/* # list all interfaces
do
INTF=$(basename $INTF_PATH) # interface name
echo "$INTF,$(ifdata -pa $INTF)" # interface name and address
done
example output for 5 interfaces, while only eth0 and lo are up:
eth0,123.234.10.12
lo,127.0.0.1
vboxnet0,NON-IP
wlan0,NON-IP
wlan1,NON-IP

Resources