CodingInTheUK
CodingInTheUK

Reputation: 948

AWK how to check if first column contains an ip address

I have a file that contains a list of DHCP bindings. I want to extract some of the data, however its not as straight forward as it first appeared it would be, often the hardware identifier is across multiple lines.

You can see those in the second column, they have a period at the end when they continue onto the next line.

So to sum up what I want to achieve here. Extract column 1 and 2 where there is an IP address and just column 2 where there is none, the end result being the IP and full hardware address on a single line.

The goal being to make it faster to get the hardware identifier, currently if I want to assign a static IP I have to perform up to three copy/pastes, not a big deal I know, but I would still like to be able to do it in one copy.

Data example:

10.x.x.x            ff9f.6e85.2400.0200.    Infinite                Manual
                    00ab.1146.a45b.6916.
                    7ae3.be
10.x.x.x            ff29.ed05.1200.0100.    Infinite                Manual
                    0128.c2e3.9300.0c29.
                    ed05.12
10.x.x.x            ff9f.6e85.2400.0200.    Infinite                Manual
                    00ab.11e7.d0ba.2f43.
                    f135.f2
10.x.x.x            ff9f.6e85.2400.0200.    Infinite                Manual
                    00ab.11b2.f37a.8a39.
                    e6bf.93
10.x.x.x            ff9f.6e85.2400.0200.    Infinite                Manual
                    00ab.115c.5da2.eecf.
                    09d7.41
10.x.x.x            000c.29a0.40a3          Feb 07 2022 05:44 PM    Automatic
10.x.x.x            01e8.3935.e98c.14       Infinite                Manual
10.x.x.x            0168.b599.bed2.94       Infinite                Manual
10.x.x.x            01d0.67e5.0530.ef       Feb 07 2022 11:54 PM    Automatic
10.x.x.x            ff29.a040.a300.0100.    Infinite                Manual
                    0129.88be.c700.0c29.
                    a040.a3

The following code I have managed to put together looking around for a solution. Searches like "awk if column 1 = ip address" came back with the regex, I am not even sure that I am using it correctly.

awk '{
    if ($1~/^[[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\]/) {
        ip="\n$1"
        addr=$2
    } else {
        addr="$1"
    }
    printf "%s %s",ip,addr;
}' data.txt

I am aware I need some way to combine the addr variable too, I can work on that later, just getting the columns correctly would be a massive help. (Think I sorted the combining part, adjusted the code to the following, removing the variables.)

awk '{
    if ($1~/^[[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\]/) {
        printf "\nIP Address: %s", $1
        printf $2
    } else {
        printf $1
    }
}' data.txt

So, if I can get help with how to check if the first column contains an IP address I should be there.

Upvotes: 0

Views: 430

Answers (2)

dan
dan

Reputation: 5251

It seems like the task here is to reformat a table.

awk '
l && /^[^[:space:]]/ {print l; l=""}
/^[^[:space:]]/ {l = "IP Address: "$1" "$2; next}
l {l = l$1}
END {if (l) {print l}}'

Prints:

IP Address: 10.x.x.x ff9f.6e85.2400.0200.00ab.1146.a45b.6916.7ae3.be
IP Address: 10.x.x.x ff29.ed05.1200.0100.0128.c2e3.9300.0c29.ed05.12
IP Address: 10.x.x.x ff9f.6e85.2400.0200.00ab.11e7.d0ba.2f43.f135.f2
IP Address: 10.x.x.x ff9f.6e85.2400.0200.00ab.11b2.f37a.8a39.e6bf.93
IP Address: 10.x.x.x ff9f.6e85.2400.0200.00ab.115c.5da2.eecf.09d7.41
IP Address: 10.x.x.x 000c.29a0.40a3
IP Address: 10.x.x.x 01e8.3935.e98c.14
IP Address: 10.x.x.x 0168.b599.bed2.94
IP Address: 10.x.x.x 01d0.67e5.0530.ef
IP Address: 10.x.x.x ff29.a040.a300.0100.0129.88be.c700.0c29.a040.a3

This works by checking if a line begins with a space (padding) or not (IP Address).

Upvotes: 1

CodingInTheUK
CodingInTheUK

Reputation: 948

I have solved my problem with help from this Answer to another question

It turns out I had the correct regex in the first place but had not implemented it correctly, when i tried it I missed the part about posix being for the command line and put it inside the if along with the regex. Positioning it outside of the braces solved it.

Here is my updated code with a regex to match an ip address in the first column.

awk --posix '{
    if ($1 ~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/) {
        printf "\nIP Address: %s %s", $1, $2
    } else {
        printf $1
    }
}' data.txt
echo ""

And the result:

IP Address: 10.x.x.x ff9f.6e85.2400.0200.00ab.1146.a45b.6916.7ae3.be
IP Address: 10.x.x.x ff29.ed05.1200.0100.0128.c2e3.9300.0c29.ed05.12
IP Address: 10.x.x.x ff9f.6e85.2400.0200.00ab.11e7.d0ba.2f43.f135.f2
IP Address: 10.x.x.x ff9f.6e85.2400.0200.00ab.11b2.f37a.8a39.e6bf.93
IP Address: 10.x.x.x ff9f.6e85.2400.0200.00ab.115c.5da2.eecf.09d7.41
IP Address: 10.x.x.x 000c.29a0.40a3
IP Address: 10.x.x.x 01e8.3935.e98c.14
IP Address: 10.x.x.x 0168.b599.bed2.94
IP Address: 10.x.x.x 01d0.67e5.0530.ef
IP Address: 10.x.x.x ff29.a040.a300.0100.0129.88be.c700.0c29.a040.a3

It's exactly how I wanted it. (added the echo to put the terminal prompt back on it's own line).

Upvotes: 0

Related Questions