-3

I have a variable like

master='172.21.154.37 172.21.250.94 172.21.251.93 172.21.250.94' and I need to check whether the first and the second column in the file both matches the variable. The following is an example, the second line, 172.21.154.37 can be found in variables $master and 172.21.250.94 can also found in $master

172.21.154.40 172.21.254.25

172.21.154.37 172.21.250.94

172.21.250.93 172.21.254.24

awk '$1 /'$master'/ {print $0 }' /tmp/newip.txt but there is an escapte issue 

awk '$1 /172.21.154.37' 172.21.250.94 172.21.251.93 '172.21.250.94/ {print $0 }' /tmp/newip.txt

issue resolved,tks

3
  • 5
    This is your third (?) question on the same general topic. What is the overall goal of what you're doing? You keep getting solutions to very specific issues, but maybe there's a better way of reaching the main goal, if we knew what it was? Commented Oct 12, 2024 at 6:53
  • 2
    I took time to edit several time, please, be respectful to not remove code blocks. Take a look at how to format my code block Commented Oct 12, 2024 at 7:18
  • Sorry,actually,we just need to create a redis cluster and make master/slave in different subnets,we have totally 3 subnets,but the cluster may have 3master/3 slave,5master/5 slave,9master /9slave etc.and in some case,the master is already created and in 3 subnets,I just need to re-arrange the slaves and make slave in different subnet with master Commented Oct 12, 2024 at 9:59

2 Answers 2

0

Your syntax on the matching is faulty, regardless of the escape issue. awk '$1 /172.21.154.37' will always be true if field 1 is non-empty: you need an operator like ~, or a function like index(). In any case, matching text containing the special character . is unwise. index() is a plain text search.

The correct method for injecting shell variables into awk scripts is to pass the value using a -v option.

awk -v master="${master}" '$1 ~ master' 

Splitting a list of IPs into an awk array, and using the in operator, is usually cleaner than pattern searches. Your double test would then be like: ($1 in List) && ($2 in List).

3
  • In addition to needing index() or in instead of ~, you'd need front and back anchors or 1.2.3.4 would match 51.2.3.4 or 1.2.3.45. Commented Oct 12, 2024 at 12:12
  • I think awk '$1 /172.21.154.37' will always be true, whether $1 is empty or not. In all cases, that is just a string so it will evaluate to true. Commented Oct 12, 2024 at 14:45
  • @Paul_Pedant I thought you'd be interested to know I just came across a youtube page where someone is sharing our answers to this question in a video, see youtu.be/YsOtRyZcNzc?feature=shared. I guess the internet has run out of content.... Commented Mar 19 at 11:37
0

See how-do-i-use-shell-variables-in-an-awk-script for how to pass the value of a shell variable to an awk script.

As @Paul_Pedant mentions in their answer, creating an awk array (targets[] below) from your master shell variable and then using in to do a hash lookup of each IP address is the most efficient and robust way to do this, e.g. Using any awk:

$ awk -v m="$master" ' BEGIN { split(m, tmp) for ( i in tmp ) { targets[tmp[i]] } } ($1 in targets) && ($2 in targets) ' file 172.21.154.37 172.21.250.94 
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.