Only get the first part of grep: get ip of ifconfig - linux

ifconfig | grep -m1 "inet addr"
Gives me
inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0
However, I only want the ip, which is 172.30.1.6. How can I do this?
Note that I have to be using ifconfig, as this is an embedded system with limited functionalities.

Get out your scissors, it's cuttin' time.
echo inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0 | cut -d : -f 2 | cut -d " " -f 1

One way to do it ..
ifconfig | grep -m1 "inet addr" | awk '{print $2}' | awk -F: '{print $2}'

If all you want to do is obtain the ip address, there might be easier ways of achieving that using say hostname -i ( reference Which terminal command to get just IP address and nothing else? )
Since others have mentioned cut and awk, I will provide a solution using sed :
echo "inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0" | sed -e "s/.*\(addr:[^ ]*\) .*/\1/"
addr:172.30.1.6
echo "inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0" | sed -e "s/.*addr:\([^ ]*\) .*/\1/"
172.30.1.6

Use cut with a delimiter
| cut -d':' -f 2 | cut -d' ' -f 1

Is this all you're trying to do?
awk -F'[: ]' '/inet addr/{print $3; exit}'
For example using cat file in place of ifconfig:
$ cat file
inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0
$ cat file | awk -F'[: ]' '/inet addr/{print $3; exit}'
172.30.1.6

Here's a way to do it with a single sed command, eliminating the call to grep:
ifconfig | sed -n '/inet addr/{s/^.*inet addr:\([^ ]*\).*$/\1/p;q}'
There are a few things going on here:
sed -n tells sed not to print every line like it normally does
/inet addr/ is a sed address - it tells sed to only operate on lines containing "inet addr"
The { and } brackets define a block of commands to be run, with the commands separated by a ;
The s command is fairly straightforward - it just captures the IP and replaces the whole line with just the IP
The p flag at the end of the s command tells sed to print the result of the substitution. This is necessary because we called sed with the -n option.
The q command tells sed to quit, so that it only processes the first line containing "inet addr".
Using the -n option, the /inet addr/ address, the p flag on the s command, and the q command, essentially has the same effect as grep -m1 "inet addr", which makes calling grep unnecessary. In fact, it's worth noting that the following commands produce identical output:
> ifconfig | grep -m1 "inet addr"
inet addr:192.168.1.1 Bcast:192.168.2.255 Mask:255.255.255.0
> ifconfig | sed -n '/inet addr/{p;q}'
inet addr:192.168.1.1 Bcast:192.168.2.255 Mask:255.255.255.0
Here, I've omitted the s/pattern/replacement/p part of the sed command, and replaced it with a p command (which just prints the whole line), just to show the effect of the other parts in isolation.

Just use the command cut.
ip a | grep -m1 "inet addr" | cut -d':' -f 2 | cut -d' ' -f 1
I also advise you to learn the use of other commands such as : wc,sed,tr,sort,uniq. They will help manipulate the output as you please. Here is a small lesson where we present you all these command : https://www.javatpoint.com/linux-filters
I hope to help you.

Using Bash's regex operator =~:
$ [[ $(ifconfig | grep -m1 "inet addr") =~ [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ ]] && echo ${BASH_REMATCH[0]}
172.30.1.6
Update: Something even better in the comments.

Related

Take output from AWK command and display line by line based on white space

I am running the following command in a bash script:
echo `netstat -plten | grep -i autossh | awk '{print $4}'` >> /root/logs/autossh.txt
The output displays in a single line:
127.0.0.1:25001 127.0.0.1:15501 127.0.0.1:10001 127.0.0.1:20501 127.0.0.1:15001 127.0.0.1:5501 127.0.0.1:20001
I would like each IP to display line by line. What do I need to do with the awk command to make the output display line by line
Just remove the echo and subshell:
netstat -plten | grep -i autossh | awk '{print $4}' >> /root/logs/autossh.txt
awk is already printing them one per line, but when you pass them to echo it parses its arguments and prints them each with a space between them. Every line of awk output then becomes a separate argument to echo so you lose your line endings.
Of course, awk can do pattern matching too, so no real need for grep:
netstat -plten | awk '/autossh/ {print $4}' >> /root/logs/autossh.txt
with gawk at least you can have it ignore case too
netstat -plten | awk 'BEGIN {IGNORECASE=1} /autossh/ {print $4}' >> /root/logs/autossh.txt
or as Ed Morton pointed out, with any awk you could do
netstat -plten | awk 'tolower($0) ~ /autossh/ {print $4}' >> /root/logs/autossh.txt
You can just quote the result of command substitution to prevent the shell from performing word splitting.
You can modify it as follows to achieve what you want.
echo "`netstat -plten | grep -i autossh | awk '{print $4}'`" >> /root/logs/autossh.txt

How to combine two different linux commands?

I use the following command to get the MAC address of the system.
ifconfig | grep enp0s20f6 | awk '{print $5}'
The following command is used to get the hash of the string:
echo -n "string to be hashed"| md5sum | awk '{print $1}'
I need to get the hashed string for the MAC address by combining both of these commands.
I tried the following, but didn't work.
ifconfig | grep enp0s20f6 | awk '{print $5}' | md5sum
md5sum /sys/class/net/eth0/address | awk '{print $1}'
Try this:
$ cat /sys/class/net/eth0/address | md5sum
Replace eth0 by the name of your interface. Hope it helps! :)
md5sum < /sys/class/net/eth0/address
This command also helps to get the md5sum of mac address

Store the return command in array Shell

I have to store the return of this command into an array
I tried this :
my_array=( $(/sbin/ifconfig | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}' | grep -v '127.0.0.1'))
but it gives me the error below:
/bin: is a directory
You could remove parenthesis as below. You can also use ip command, its newer version and more powerful than ifconfig.
my_array=$(ip addr show | grep -Po 'inet \K[\d.]+' | grep -v 127.0.0.1)
In my GNU bash 4.4.0(1), ifconfig is not giving me inet addr: but just inet like this:
inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
inet 127.0.0.1 netmask 255.0.0.0
In any case the error you receive doesn't make sense to me.
I can get the IP address combining grep & awk like this:
sbin/ifconfig | grep -v "127.0.0.1" |grep 'inet ' |awk -F" " '{print $2}'
(awk -F" " : Field Seperator. Field Seperator in my case is space.)
Also this works for me , due to the fact that 127.0.0.1 goes to the end:
/sbin/ifconfig |grep -m1 'inet '| awk -F" " '{print $2}
(grep -m1 = stop after first match)
PS: If you have plans to append your array , you need to use my_array+=(...)

Find network interface by IP address - Linux/Bash

I'm wondering how I can query by IP address using sed, and it will show which interface name that is using it.
For example..
ipconfig -a | grep 10.0.0.10
I would expect it to come back with ETH0
ifconfig | grep -B1 10.0.0.10 | grep -o "^\w*"
You should use this comand :
ifconfig | grep -B1 "inet addr:10.0.0.10" | awk '$1!="inet" && $1!="--" {print $1}'
Hope this help !
ip -br -4 a sh | grep 10.0.0.10 | awk '{print $1}'
If you want sed specific solution you may try this. Its little hard to digest how it works , but finally this combination works.
ifconfig | sed -n '/addr:10.0.0.10/{g;H;p};H;x' | awk '{print $1}'
If you want to take it as an argument via script use "$1" or so instead if 10.0.0.10.
Sed manual for reference : http://www.gnu.org/software/sed/manual/sed.html#tail

How to extract version from a single command line in linux?

I have a product which has a command called db2level whose output is given below
I need to extract 8.1.1.64 out of it, so far i came up with,
db2level | grep "DB2 v" | awk '{print$5}'
which gave me an output v8.1.1.64",
Please help me to fetch 8.1.1.64. Thanks
grep is enough to do that:
db2level| grep -oP '(?<="DB2 v)[\d.]+(?=", )'
Just with awk:
db2level | awk -F '"' '$2 ~ /^DB2 v/ {print substr($2,6)}'
db2level | grep "DB2 v" | awk '{print$5}' | sed 's/[^0-9\.]//g'
remove all but numbers and dot
sed is your friend for general extraction tasks:
db2level | sed -n -e 's/.*tokens are "DB2 v\([0-9.]*\)".*/\1/p'
The sed line does print no lines (the -n) but those where a replacement with the given regexp can happen. The .* at the beginning and the end of the line ensure that the whole line is matched.
Try grep with -o option:
db2level | grep -E -o "[0-9]+\.[0-9]+\.[0-9]\+[0-9]+"
Another sed solution
db2level | sed -n -e '/v[0-9]/{s/.*DB2 v//;s/".*//;p}'
This one desn't rely on the number being in a particular format, just in a particular place in the output.
db2level | grep -o "v[0-9.]*" | tr -d v
Try s.th. like db2level | grep "DB2 v" | cut -d'"' -f2 | cut -d'v' -f2
cut splits the input in parts, seperated by delimiter -d and outputs field number -f

Resources