maihabunash
maihabunash

Reputation: 1702

grep + how to ignore many cases of marked ,lines

I need to capture the machine_VIP (exactly match ) from /etc/hosts file

the problem is that in hosts file there are some lines with machine_VIP but they remarked before the machine_VIP or the line is remarked

so in this case we need to ignore the those lines

meenwhile I write the following command in order to get the IP that exists in the line with machine_VIP but it doesn’t took the right IP because the remarked character #

 Cluster_VIP=` grep -iw machine_VIP /etc/hosts | awk '{print $1}' | head -1  `

example: ( of my hosts file )

  5.5.5.5  GH_T  T1 T2 T3 # machine_VIP
  # 198.2.3.12 MON1 MON2  machine_VIP
  18.2.4.12 W1 # machine_VIP # machine_VIP # machine_VIP
  192.9.200.77 machine_linux1 machine_linux2  machine_VIP
  192.9.200.78 machine_linux10 machine_linux20 machine_VIP_test

please advice what I need to add in my command in order to get the right matched IP

according to the example below the expected results should be:

 echo $Cluster_VIP

 192.9.200.77

Upvotes: 1

Views: 229

Answers (4)

Sriharsha Kalluru
Sriharsha Kalluru

Reputation: 1823

You can use getent command to get it done instead of grep command.

[root@myserver ~]# cat /etc/hosts
5.5.5.5  GH_T  T1 T2 T3 # machine_VIP
# 198.2.3.12 MON1 MON2  machine_VIP
18.2.4.12 W1 # machine_VIP # machine_VIP # machine_VIP
192.9.200.77 machine_linux1 machine_linux2  machine_VIP
192.9.200.78 machine_linux10 machine_linux20 machine_VIP_test

[root@myserver ~]# Cluster_VIP=$(getent hosts machine_VIP |awk '{print $1}')
[root@myserver ~]# echo $Cluster_VIP
192.9.200.77

Upvotes: 3

SMA
SMA

Reputation: 37023

Try this:

grep -w '^[^#]* machine_VIP' /etc/hosts | head -1 | awk '{print $1}'

First grep - exact word match for machine_VIP with same case in /etc/hosts file

second grep - to ignore all the rows which contains #

Awk - to print ip address

head - to print first row for output.

Upvotes: 0

gniourf_gniourf
gniourf_gniourf

Reputation: 46833

How about this single sed statement?

sed -n '/^[^#]*\bmachine_VIP\b/s/[[:space:]].*//p' /etc/hosts

(uses GNU \b for word boundary—this can be easily modified to not use GNU extensions).

Or, since you're using Bash, you could use grep as so:

read -r Cluster_VIP _ < <(grep '^[^#]*[[:space:]]machine_VIP\([[:space:]]\|$\)' /etc/hosts)

No chain of awk, tail, grep, etc. needed.

Or, with a single awk:

Cluster_VIP=$(awk '/^[^#]*[[:space:]]machine_VIP([[:space:]]|$)/ {print $1;exit}' /etc/hosts)

Now, a pure Bash possibility, so that you'll be sure it'll run anywhere Bash is installed:

while IFS= read -r line; do
    [[ $line =~ ^[^#]*[[:space:]]machine_VIP([[:space:]]|$) ]] || continue
    read -r Cluster_VIP <<< "$line"
    break
done < /etc/hosts

if [[ $Cluster_VIP ]]; then
    echo "$Cluster_VIP"
else
    echo >&2 "Cluster VIP not found"
    exit 1
fi

Upvotes: 1

John Zwinck
John Zwinck

Reputation: 249213

grep -w '^[^#]* machine_VIP' /etc/hosts | head -1 | awk '{print $1}'

This searches for a line which has machine_VIP with no # before it.

Upvotes: 1

Related Questions