Reputation: 139
I have two Linux machines. One is 4.4.12-99, one is 4.4.143. I just ran apt upgrade on them both.
I have an awk statement that contains a regex that works on 4.4.143, but fails on 4.4.12-99. I have searched for days and tried multiple different syntaxes to discover what can be wrong. awk is not failing or complaining, it's just not matching the word boundary. The scripts are the same on each machine and work fine except for this awk statement. On the one that is not working properly, I can cause it to match everything and provide that result.
ip=$(awk -v sUSER="$sUSER" 'BEGIN{gsub(/\./,"\\.",sUSER)}match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) && $0 ~ ("[^[:alnum:]]"sUSER"$") && $0 !~ /^$/ && $0 !~ /^#/{print $1}' /etc/hosts )
awk looks into the /etc/hosts file with a variable, $sUSER and tried to match a user to an associated IP address.
I cant figure out what I am doing wrong.
Upvotes: 2
Views: 4916
Reputation: 246807
hek2mgl's answer is what you should use.
For your awk question, GNU awk regular expressions are documented here: https://www.gnu.org/software/gnulib/manual/html_node/gnu_002dawk-regular-expression-syntax.html
They use \<
and \>
as zero-width word boundary markers, so you can do
gawk -v sUSER="$sUSER" '
BEGIN {
gsub(/\./,"\\.",sUSER)
ipv4Re = "^[0-9]+(\\.[0-9]+){3}$"
sUserRe = "\\<" sUSER "\\>"
}
/^$/ || /^#/ {next}
$1 ~ ipv4Re && $0 ~ sUserRe {print $1}
' /etc/hosts
(whitespace is nice, you should try using it)
another approach is looping over the fields and using string equality which automatically encompasses word boundaries. This will work with gawk or mawk
awk -v sUSER="$sUSER" '
!/^#/ {for (i=2; i<=NF; i++) if ($i == sUSER) print $1}
' /etc/hosts
Upvotes: 5
Reputation: 157990
What you basically want to do is a local hostname lookup. There is a tool called getent
for that purpose:
getent -s files hosts "${sUSER}" | cut -d' ' -f1
-s files
tells getent
to only use the local host databases (not DNS) which is /etc/hosts
.
Upvotes: 2