I have to set 3 variables depending on the IP address.
I discovered that I can use switch with -regex, but I don't know how to check if address is between two addresses.
$ip = (get-WmiObject Win32_NetworkAdapterConfiguration|Where {$_.Ipaddress.length -gt 1}).ipaddress[0]
switch -regex ($ip)
{
"address 192.168.0.1-192.168.0.255" { $val = 3; }
"address 192.168.1.1-192.168.1.100" { $val = 1; }
"address 192.168.1.101-192.168.1.200" { $val = 4; }
"address 192.168.1.201-192.168.1.255" { $val = 5; }
default { exit }
}
I don't think regex is the best way of handling this. I'd probably do something like this
$ip = (get-WmiObject Win32_NetworkAdapterConfiguration|Where {$_.Ipaddress.length -gt 1}).ipaddress.split('.')
switch ($ip)
{
{$ip[2] -eq 0} { $val = 3; } #match anything in 192.168.0.1-255
{$ip[3] -in 1..100} { $val = 1; }
{$ip[3] -in 101..200} { $val = 4; }
{$ip[3] -in 201..255} { $val = 5; }
default { exit }
}
$val
If your IP blocks are different than what was provided in the example it would just be a matter of adjusting the switch conditions to match the appropriate octets
Related
I'm looking to build a Node class in Perl (using the keyword 'package'), but I'm not sure how to create a pointer to class variable like in C++.
In C++, you have:
class Node
{
public:
int key;
Node* left;
Node* right;
Node(int _key)
{
key = _key;
left = NULL;
right = NULL;
}
};
In Perl:
package Node;
sub Node
{
my $class = shift;
my $key;
Node* left; # Of course, this will not work
Node* right;
}
Is there any way I could make a pointer to class variable in Perl? Or if it's not possible, any suggestions on Perl modules that could do what I want to do?
package Node;
use strict;
use warnings qw( all );
use Carp qw( croak );
sub new {
my ($class, %args) = #_;
croak("key is required") if !exists($args{key});
my $self = bless({}, $class);
$self->{ key } = $args{ key };
$self->{ left } = $args{ left };
$self->{ right } = $args{ right };
return $self;
}
sub key { my $self = shift; $self->{ key } = shift if #_; $self->{ key } }
sub left { my $self = shift; $self->{ left } = shift if #_; $self->{ left } }
sub right { my $self = shift; $self->{ right } = shift if #_; $self->{ right } }
1;
or
package Node;
use strict;
use warnings qw( all );
use Moo;
use namespace::clean;
has key => ( is => 'rw', required => 1 );
has left => ( is => 'rw' );
has right => ( is => 'rw' );
1;
Usage:
my $node = Node->new(
key => $key,
left => $left, # Optional. Defaults to undef.
right => $right, # Optional. Defaults to undef.
);
Actually if you want to use OOP in Perl you should check out existing frameworks like Moose or do it yourself using bless. An example:
package Node;
sub new {
my ($class, $key) = #_;
bless { key => $key }, $class;
}
my $node = Node->new();
Later on, you can add the "pointers" to the "object" by adding references to the nodes to the hash inside node.
I trying to get my hands dirty with PHPSpec.
Basically Im trying to make a TimeSpan as a practice.
I want to make sure that all possible valid inputs are accepted.
function it_can_be_created_from_24_format()
{
$hours = 24;
$minutes = 60;
$seconds = 60;
for ($h = 1; $h < $hours; $h++) {
for ($m = 1; $m < $minutes; $m++) {
for ($s = 1; $s < $seconds; $s++) {
$this->beConstructedThrough('fromString', [$this->buildTimeString($h, $m, $s)]);
$this->shouldNotThrow(\InvalidArgumentException::class)->duringInstantiation();
$this->getHours()->shouldBe($h);
$this->getMinutes()->shouldBe($m);
$this->getSeconds()->shouldBe($s);
}
}
}
}
private function buildTimeString($h, $m, $s)
{
$minutes = ($m < 9) ? '0'.$m : $m;
$seconds = ($s < 9) ? '0'.$s : $s;
return sprintf('%s:%s:%s', $h, $minutes, $seconds);
}
But im receiving this error:
you can not change object construction method when it is already instantiated
I got this kind of CSV file:
name,x-extension,value,extra
"Roger","9890","",""
"Nicole","9811","president, ceo",""
...
Now, I want the find the maximum size of each field in the file. So I used this awk script:
Updated script:
NR==1 {
gsub(/\r/,"",$0) #remove linefeed from last field name
for (n = 1; n <= NF; n++) {
colname[n]=$n;
maxlen[n]=-1;
}
nbrField = NF; # will get bump +2 by the new FS
FS="\",\"|^\"|\"$";
}
NR>1 {
for (n = 2; n <= nbrField+1; n++) {
if (length($n)>maxlen[n-1]) {
maxlen[n-1]=length($n);
}
}
}
END {
for(i = 1; i <= nbrField; i++) {
printf "%s : %s\n", colname[i], maxlen[i]
}
}
The problem a got is I need to change the field separator AFTER reading the first line because as you can see, the header don't use double quote for field delimiter and there is coma INSIDE some field.
I tried to play with this -F option on my awk command line but I can't find the right combination of regex to do the trick..
> awk -F'", "|^"|"$' -f myprog mydata ==>(don't work)
Help! :-)
Change FS in the block that processes the first line:
NR==1 {
for(n = 1; n <= NF; n++) {
colname[n]=$n
}
FS="\",\"|^\"|\"$"
}
I prefer to use a real CSV parser for CSV data. For example, Perl:
perl -MText::CSV -MList::Util=max -nE '
BEGIN {$csv = Text::CSV->new({binary=>1})}
$csv->parse($_);
#row = $csv->fields();
if ($. == 1) {
#h = #row; $n = $#row;
}
else {
$max{$h[$_]} = max($max{$h[$_]}, length $row[$_]) for (0..$n)
}
END {
while (($k,$v) = each %max) {say join ":", $k, $v}
}
' << DATA
name,x-extension,value,extra
"Roger","9890","",""
"Nicole","9811","president, ceo",""
DATA
value:14
name:6
extra:0
x-extension:4
I want to change a perl script that executes a loop some times, and I want to pass the number of loops by command line option. The program now receives some options, then I need to change it to receive a new parameter, but it is the first time I see a perl script, then I don't know how to change.
The start of program (to parse command line options) is:
if ($#ARGV >= 1) {
for ($i = 1; $i <= $#ARGV; $i++) {
if ($ARGV[$i] =~ /^\-/) {
if ($ARGV[$i] =~ /\-test/) {
//do something
}
} else {
//do something other
}
}
}
I think that I must put something like:
if ($ARGV[$i] =~ /^\-L40/)
But it only match to 40, I don't know how to parse the number attached to the -L parameter to use for the loop limit.
Thanks in advance and sorry if there is any similar question, but I don't find any.
use Getopt::Long qw( );
sub usage {
print(STDERR "usage: prog [--test] [-L NUM]\n");
exit(1);
}
GetOptions(
'test' => \my $opt_test,
'L=i' => \my $opt_L,
)
or usage();
die("-L must be followed by a positive integer\n")
if defined($opt_L) && $opt_L < 1;
Something like:
my $loopLimit = 1; # default
if ($#ARGV >= 1)
{
for ($i = 1; $i <= $#ARGV; $i++)
{
if ($ARGV[$i] =~ /^\-/)
{
if ($ARGV[$i] =~ /\-test/)
{
# do something
}
elsif ($ARGV[$i] =~ /\-L(\d+)/) # -L followed by digits
{
$loopLimit = $1;
}
}
else
{
# do something other
}
}
}
I'm writing a compiler, and I have working code for handling infinitely nested if statements, but it's kind of a hack. I don't know if it's safe to do this?
con_statement:
IF exp DO
{
$1 = ifNum++;
if($2 == BOOLEAN_TYPE || $2 == INTEGER_TYPE)
{
utstring_printf(code, "\tpop\teax\n");
utstring_printf(code, "\tcmp\teax, 0\n");
utstring_printf(code, "\tje\tIF_END_%d\n", $1);
}
if($2 == FLOAT_TYPE)
{
utstring_printf(code, "\tnop\n");
}
}
program FI
{
utstring_printf(code, "IF_END_%d:\n", $1);
}
;
This works fine but it would be IMO clearer to use $$/$4:
con_statement:
IF exp DO
{
$$ = ifNum++;
if($2 == BOOLEAN_TYPE || $2 == INTEGER_TYPE)
{
utstring_printf(code, "\tpop\teax\n");
utstring_printf(code, "\tcmp\teax, 0\n");
utstring_printf(code, "\tje\tIF_END_%d\n", $$);
}
if($2 == FLOAT_TYPE)
{
utstring_printf(code, "\tnop\n");
}
}
program FI
{
utstring_printf(code, "IF_END_%d:\n", $4);
}
;
The first action is generating a value (which it puts into $$), and then later actions can access that value.
Alternately (and particularly if you want to support ELSE), it may make sense to split this initial action onto a separate production:
con_statement:
if_head program FI
{ utstring_printf(code, "IF_FALSE_%d:\n", $1); }
| if_head program ELSE
{ utstring_printf(code, "\tjmp\tIF_END_%d\n", $1);
utstring_printf(code, "IF_FALSE_%d:\n", $1); }
program FI
{ utstring_printf(code, "IF_END_%d:\n", $1); }
;
if_head:
IF exp DO
{ $$ = ifNum++;
:
;
This allows using the same action for plain if and if/else, avoiding a grammar conflict, since at the point you are parsing the IF..DO you don't know whether there will be an ELSE or not.