Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Script to convert HBA WWNs to lowercase and add ":"[Updated]

by perl514 (Pilgrim)
on Dec 17, 2011 at 15:56 UTC ( #944083=CUFP: print w/ replies, xml ) Need Help??

Hi,

I hope that SAN Admins find this helpful.

Whenever HBA WWNs are entered in Cisco SAN Switches on the command line prompt, A colon (:) character needs to be added at every second position in the WWN. Also, the WWN has to be lower case.

So in case you get a WWN like so - 10000000C9ABCDEF it needs to be converted to lower case and : needs to be added. The following script does this:

#!/usr/bin/perl use warnings; use strict; my $wwn = 0; until ( $wwn eq "q") { print "Enter the wwn or q to quit: "; chomp ($wwn=<STDIN>); my @wwn = unpack ("(a2)*", lc($wwn)); @wwn = join (":", @wwn); print "@wwn\n"; }
===============================================================================

Here is the updated version of the same script.

Here it adds ":" and lowercase. It also checks if the characters entered are Hex, if the length is correct and if any unwanted characters are given or not. In these cases, it takes you back to the prompt to enter the WWN.

It also does it the other way around, i.e. if you enter a WWN with ":", it removes them and does all the checks as mentioned above.

GrandFather and Not_a_Number thank you very much for your kind inputs.

I tried using the suggestions given by GrandFather in the other thread, but for some reason I could not tweak it enough to work.

Here is the script:

#!/usr/bin/perl use warnings; use strict; print "Enter a for lowercase and colons. b to do it the other way around. q to quit "; my $choice = 0; my $raw_wwn = 0; my $ripe_wwn = 0; my @array_wwn; my @ripe_wwn; chomp ($choice = <STDIN>); if ($choice eq "a") { until ( $raw_wwn eq "q") { print "Enter the wwn or q to quit: "; chomp ($raw_wwn=<STDIN>); if (length($raw_wwn)!=16 || $raw_wwn =~/[^0-9a-fA-F]/ ) { print "Invalid Length Or Incorrect Format\n"; } else { my @array_wwn = unpack ("(a2)*", lc($raw_wwn)); @ripe_wwn = join (":", @array_wwn); print "@ripe_wwn\n"; } } } elsif ($choice eq "b") { $raw_wwn =0; until ($raw_wwn eq "q") { print "Enter the wwn with : or q to quit: "; chomp ($raw_wwn=<STDIN>); if (length($raw_wwn)!=23||$raw_wwn=~/[^:a-fA-F0-9]/) { print "Invalid Length Or Incorrect Format\n"; } else { $raw_wwn=~ s/://g; $ripe_wwn = $raw_wwn; print lc($ripe_wwn), "\n"; } } }#closing for if choice =b elsif ($choice eq "q") { exit; }

And here is some test output:

[perlpetual@joesatch practice]$ perl wwn_final.pl Enter a for lowercase and colons. b to do it the other way around. q to quit a Enter the wwn or q to quit: 10000000C9ABCDEF 10:00:00:00:c9:ab:cd:ef Enter the wwn or q to quit: 10:00:00:00:c9:ab:cd:ef Invalid Length Or Incorrect Format Enter the wwn or q to quit: 10000000C9ABCDEG Invalid Length Or Incorrect Format Enter the wwn or q to quit: 10000000abcdefga Invalid Length Or Incorrect Format Enter the wwn or q to quit: 10000000abcdefab 10:00:00:00:ab:cd:ef:ab Enter the wwn or q to quit: q Invalid Length Or Incorrect Format [perlpetual@joesatch practice]$ perl wwn_final.pl Enter a for lowercase and colons. b to do it the other way around. q to quit b Enter the wwn with : or q to quit: 10:00:00:00:c9:ab:cd:ef 10000000c9abcdef Enter the wwn with : or q to quit: 10:00:00:00:c9:ab:cd:eg Invalid Length Or Incorrect Format Enter the wwn with : or q to quit: 10:00:00:00:c9:ab:cd:e Invalid Length Or Incorrect Format Enter the wwn with : or q to quit: 10000000c9abcdef Invalid Length Or Incorrect Format Enter the wwn with : or q to quit: q Invalid Length Or Incorrect Format [perlpetual@joesatch practice]$
Perlpetually Indebted To PerlMonks.

Comment on Script to convert HBA WWNs to lowercase and add ":"[Updated]
Select or Download Code
Re: Script to convert HBA WWNs to lowercase and add ":"
by keszler (Priest) on Dec 17, 2011 at 17:05 UTC

    ++ for a handy utility

    Golf anyone?

    perl -E'say join":",grep$_,split/(..)/,lc"10000000C9ABCDEF"' 10:00:00:00:c9:ab:cd:ef

      Ok. Fore!

      #perl -E'say join":",grep$_,split/(..)/,lc"10000000C9ABCDEF"' perl -E"$_=lc'10000000C9ABCDEF';s/..(?=.)\K/:/g;say" 10:00:00:00:c9:ab:cd:ef

        Nice! I learned something.

        I like to "correctly" handle the case where there may already be colons in the string.
        perl -E"$_=lc'02468ACE';s/[^:]{2}(?=[^:])\K/:/g;say" 02:46:8a:ce perl -E"$_=lc'02:46:8A:CE';s/[^:]{2}(?=[^:])\K/:/g;say" 02:46:8a:ce

      Hi keszler,

      Thank you for the encouragement. I have posted and updated version of the script. Kindly take a look and let me know.

      Perlpetually Indebted To PerlMonks

Re: Script to convert HBA WWNs to lowercase and add ":"
by perl514 (Pilgrim) on Dec 17, 2011 at 18:32 UTC
    whee, May be I should take this off. I just put it there for a newbie Perl Guy like me who is a fellow SAN Admin looking for script like this. You guys are so good, you wrote a oneliner...God knows when I will be able to write like you folks... :)
    Perl Version - (v5.14.2) MSWin32-x64-multi-thread on Windows 7 64 Bit.

      perl514:

      No, you should leave it on. When you're learning perl (or any other language for that matter), it's good to write in a simple straightforward manner. As you get more experienced and learn more idioms, you'll start writing tighter code.

      It's just like talking about a new field. At first you find the language that the experts use hard to understand, and you have to use normal English (or whatever the local language is). As you get more involved in the field, you start picking up the subtleties of the jargon used, and you become familiar with it. It's a gradual process, and you're not usually aware of it. Until someone new comes up to you and starts talking and you become aware of what you learned.

      So your node will be immediately useful and easy to modify for someone newer to the language. And the tighter bits will help serve as a Rosetta Stone for people learning more advanced bits of the language. Most of all, have fun with it.

      If you're really wanting to learn the weird bits of the language, play with the obfuscations & golf challenges.

      ...roboticus

      When your only tool is a hammer, all problems look like your thumb.

        Hi Roboticus,

        Thank you for the encouragement. I have posted and updated version of the script.

        Perlpetually Indebted To PerlMonks

      In addition to what roboticus said above, golfed solutions are often not what you would want to use as production code. Golf is like a workout for the mind. It keeps you in shape, but is not the real purpose (unless you make money by lifting large amounts of weight and putting it back down).

      Golf solutions explore the corner regions of the language where few people explore. The creativity required to produce some of these solutions make them unacceptable for use in anything more than an exercise. When writing production code, you are writing:

      • to codify an algorithm
      • to effectively communicate that algorithm to future maintainers, including yourself
      The second item, especially the effectively part, can be lost in the golfing process.

      --MidLifeXis

Re: Script to convert HBA WWNs to lowercase and add ":"
by GrandFather (Cardinal) on Dec 18, 2011 at 02:52 UTC

    For those who come across this thread in the future you should also read replies to Getting "un initialized value" error though variable is initialized. Please help. for discussion of some of the style decisions shown in this code. In particular there is discussion concerning the overloading of the variable name wwn and samples of more conventional indentation than shown here.

    True laziness is hard work

      Hi GrandFather,

      Thanks a lot for your guidance. I have put up and updated version of the script. Kindly note that I could not tweak it using your suggestions. Some errors kept creeping up. But here it is. Kindly let me know if there are any improvements that can be done to this.

      Perlpetually Indebted To PerlMonks

Re: Script to convert HBA WWNs to lowercase and add ":"
by Not_a_Number (Parson) on Dec 18, 2011 at 19:21 UTC

    IMO, your script would be more useful if it included some input validation. After the line:

    chomp ($wwn=<STDIN>);

    I would suggest adding:

    die "Input must be 16 characters\n" unless 16 == length $wwn; die "Invalid hex digit '$1'\n" if $wwn =~ /([^[:xdigit:]])/;

    Update: changed allowed input length from 10 (where did I get that number from?) to 16, as per WWN spec.

      Hi Not_a_Number,

      I have put up an updated version of the script. Its got all the checks that you suggested and some more. :)

      Perlpetually Indebted To PerlMonks

Re: Script to convert HBA WWNs to lowercase and add ":"
by perl514 (Pilgrim) on Dec 19, 2011 at 06:06 UTC

    Hi Not_A_Number,

    Thats what I was looking for sire !!

    Infact I have posted the updated version of this in the SoPW, here is the link - http://www.perlmonks.org/?node_id=944104

    I will use your suggestions and update it soon. Thank you very much.

    Perl Version - (v5.14.2) MSWin32-x64-multi-thread on Windows 7 64 Bit.
Re: Script to convert HBA WWNs to lowercase and add ":"[Updated]
by GrandFather (Cardinal) on Dec 28, 2011 at 23:33 UTC

    If you find yourself writing essentially the same code multiple times consider using a subroutine. Consider:

    #!/usr/bin/perl use warnings; use strict; my $mode = fetch('Enter mode', 1); while (my $raw_wwn = fetch($mode eq 'a' ? "wwn (no ':')" : "wwn with ' +:'")) { if ($mode eq 'a') { if ($raw_wwn =~ /[^0-9a-fA-F]{16}$/) { print "Invalid Length Or Incorrect Format\n"; } else { print join (":", unpack ("(a2)*", lc ($raw_wwn))), "\n"; } next; } if ($raw_wwn =~ /[^:a-fA-F0-9]{23}$/) { print "Invalid Length Or Incorrect Format\n"; next; } $raw_wwn =~ s/://g; print "$raw_wwn\n"; } sub fetch { my ($prompt, $key) = @_; $prompt .= ' or q to quit' if $prompt; while (1) { print <<KEY if $key; Enter a for lowercase and colons. b to do it the other way around. q to quit KEY print "$prompt: " if $prompt; my $answer = lc <>; chomp $answer; exit if $answer eq 'q'; return $answer if $key && $answer =~ /^[ab]$/; return $answer if ! $key; print qq{"$answer" is not a valid mode.\n\n}; } }

    In addition to drawing the prompting, input code and initial validation into one place, the code above uses fewer variables and those it does use are declared in the smallest sensible scope. The code also uses "early exits" (the return statements and next statements) to avoid extra levels of indentation and to (hopefully) make the logic flow clearer. Trivial cases (like the quit handling) are dealt with first.

    Note the use of consistent indentation. Although I tend to write using this indentation style anyway, my editor is fairly smart about indentation and I use Perl::Tidy as a final pass over the code to clean up anything I've missed. Clear consistent indentation and use of white space helps a lot in making scripts understandable.

    True laziness is hard work

      Respected GrandFather,

      Thank you once again for the updates. I will surely follow up on the valuable suggestions you have provided. As usual, your suggestions are loaded with stuff that's completely new to me, and some stuff seems quite dense to absorb at first go for a newbie like me. But without guidance of you great folks here at PerlMonks, this would be a very difficult journey. You took time out of the Chrismas Vacations to reply to my query, this fact itself speaks volumes of the ever helping nature of the PerlMonks.

      I ran the code you provided and found that certain outputs were different. But thats ok, I will work through these.

      Basically, I had put the validation in the IF loop and put the actual execution in the ELSE loop because, if I dont do that and enter 10:00:00:00:c9:ab:cd:ef in prompt "a" where a user is supposed to enter WWN without ":", then I get "10::0:0::00::0:0::c9::a:b::cd::e:f". Notice the "::". I wanted the script to check in the beginning itself if the input contains ":", or if input contains non hex characters or if the input characters are less or more than the number of WWN elements.

      Similarly in option "b", if user enters a non hex WWN or a WWN that has anything else than Hex or ":", I wanted to throw an error message which is again why I have entered the checking part in the IF loop and the actual execution in the ELSE Loop

      I never thought that programming in Perl will be so much fun...heck, now its sort of getting a little addictive, I keep thinking of ways to make my script better. Actually, its not a big deal for you guys to write scripts like these, but for me, this script means a lot. :)

      Perlpetually Indebted To PerlMonks

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://944083]
Approved by keszler
Front-paged by keszler
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (11)
As of 2014-08-27 21:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (253 votes), past polls