Solved

re-format an output

Posted on 2011-02-28
7
150 Views
Last Modified: 2012-06-22
Hello,

I am working with a perl script that reads a file named "static.leases.conf"

I have tried to modify the code but I cant get it do what I need. I am not sure how to move forward. I would like some help please.

The contents of the file needs to be re-complied like so. There are two types of information,
1. networks from "# 10.3.2.0/24 Network Static IP's" line in each section
2. Roaming address (that has no IP addr) but has a MAC
3  hosts with ip addresses and mac addresses, append the mac address with ':<mac>' to the ipaddress

The format of the output for 1 needs to be like:

add-networks.txt for a list of networks with mask ( I need to set the network first to import the IP's into first.

conf network add 10.3.2.0/24
conf network add 10.101.16.0/24

Format for option 3
Host-IP-MACreport.txt


conf zone foo.com add host test 10.3.2.10:00:FE:00:01:02:03
conf zone foo.com add host test 10.101.16.30:00:YT:91:04:01:20

The format, for output 2 needs to be like

report-Roaming-hosts.txt

conf network add fixed myroamer aa:bb:cc:11:22:33
conf network add fixed south-farm4-hp aa:cc:d1:13:12:73

use strict;

my $block_level = 0;
my $in_group_scope = 0;
my $group_scope_block_level = 0;
my $group_option_domain;
while (<>) {
       next if (/^\s*Network Static IP's/);
        if (/^\s*group\s*{/) {
                $in_group_scope = 1;
                $group_scope_block_level = $block_level;
                $block_level++;
                print "#$_";
                next;
        }
        if ($in_group_scope && /(option host-name\s\hardware ethernet\s+fixed-address\s+".*";)/) {
                $group_option_domain = $1;
                print "#$_";
                next;
        }
        if (/{\s*$/) {
                $block_level++;
        } elsif (/^\s*}/) {
                $block_level--;
                if ($in_group_scope && $group_scope_block_level == $block_level) {
                        $in_group_scope = 0;
                        $group_scope_block_level = 0;
                       # $group_option_domain = '';
                        print "#$_";
                        next;
               }
        }
        print $_;
        if ($in_group_scope && /pool/) {
                print "  " x $block_level . $in_group_scope . "\n";
        }
}

Open in new window

0
Comment
Question by:richsark
  • 5
  • 2
7 Comments
 
LVL 1

Author Comment

by:richsark
Comment Utility
Attached is the master file. dhcpd.staticleases.txt
0
 
LVL 1

Author Comment

by:richsark
Comment Utility
Hi, just a ping to broaden the audience.

Regards
0
 
LVL 2

Expert Comment

by:clayhopkins
Comment Utility
Hi, couple questions to clarify that you aren't shorthanding your source file.  I don't see any open statements for your input file, and all of your prints are going to the console.  Are you redirecting output to your files?

Second, the if statement that starts with if ($in_group_scope... has an extra "\" character in front of "hardware".  The combo of the "\" and the "h" will try to match horizontal white space, so that regex will never match.

Lastly, are you getting any errors when it runs, or just nothing happens?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 1

Author Comment

by:richsark
Comment Utility
Hi clayhopkins:

I did not re-direct yet. I wanted to see it on screen first to make sure.

So what your saying is that I need the code to look like this?

changed this line

from

if ($in_group_scope && /(option host-name\s\hardware


to
if ($in_group_scope && /(option host-name\s hardware

Does the below look like it will work and produce me the right 3 output files?

Thanks for your attention :)

use strict;

my $block_level = 0;
my $in_group_scope = 0;
my $group_scope_block_level = 0;
my $group_option_domain;
while (<>) {
       next if (/^\s*Network Static IP's/);
        if (/^\s*group\s*{/) {
                $in_group_scope = 1;
                $group_scope_block_level = $block_level;
                $block_level++;
                print "#$_";
                next;
        }
        if ($in_group_scope && /(option host-name\s hardware ethernet\s+fixed-address\s+".*";)/) {
                $group_option_domain = $1;
                print "#$_";
                next;
        }
        if (/{\s*$/) {
                $block_level++;
        } elsif (/^\s*}/) {
                $block_level--;
                if ($in_group_scope && $group_scope_block_level == $block_level) {
                        $in_group_scope = 0;
                        $group_scope_block_level = 0;
                       # $group_option_domain = '';
                        print "#$_";
                        next;
               }
        }
        print $_;
        if ($in_group_scope && /pool/) {
                print "  " x $block_level . $in_group_scope . "\n";
        }
}

Open in new window

0
 
LVL 2

Accepted Solution

by:
clayhopkins earned 500 total points
Comment Utility
Based on the example output you specified, you don't want all of the text of the options lines, just the values.  Try the following regex for that if statement:

/[option host-name|hardware ethernet|fixed-address]\s+\"*(.*)\"*;/

Open in new window


This regex will match the three option lines, with only the values of the options placed in $1.

For example, the following line:
    option host-name "mediator"

Open in new window

would put "mediator" into $1, minus the quotes.  The pipe "|" characters in the regex make it an OR operation, and placing the quotes outside of the parens will strip them off of the host name strings.

After the regex is working you'll need to trace through and make sure your block_level flags are being incremented and decremented correctly.
0
 
LVL 1

Author Comment

by:richsark
Comment Utility
So, clayhopkins, The formatted code would look like..
use strict;

my $block_level = 0;
my $in_group_scope = 0;
my $group_scope_block_level = 0;
my $group_option_domain;
while (<>) {
       next if (/^\s*Network Static IP's/);
        if (/^\s*group\s*{/) {
                $in_group_scope = 1;
                $group_scope_block_level = $block_level;
                $block_level++;
                print "#$_";
                next;
        }
        if ($in_group_scope &&/[option host-name|hardware ethernet|fixed-address]\s+\"*(.*)\"*;/) {
                $group_option_domain = $1;
                print "#$_";
                next;
        }
        if (/{\s*$/) {
                $block_level++;
        } elsif (/^\s*}/) {
                $block_level--;
                if ($in_group_scope && $group_scope_block_level == $block_level) {
                        $in_group_scope = 0;
                        $group_scope_block_level = 0;
                       # $group_option_domain = '';
                        print "#$_";
                        next;
               }
        }
        print $_;
        if ($in_group_scope && /pool/) {
                print "  " x $block_level . $in_group_scope . "\n";
        }
}

Open in new window

0
 
LVL 1

Author Comment

by:richsark
Comment Utility
Hi,

just want to confirm code on top looks correct
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Active Directory replication delay is the cause to many problems.  Here is a super easy script to force Active Directory replication to all sites with by using an elevated PowerShell command prompt, and a tool to verify your changes.
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now