How do I increment an alphanumeric string using awk?
February 5, 2009 6:41 PM Subscribe
How do I increment an alphanumeric string using awk?
I have a utility that shows me the WWID of the first port of a dual port HBA card. The second port is not explicitly listed, however it is always one digit higher than the first.
So, given that port a = 500062b0000eb5a4 -- then I know port b = 500062b0000eb5a5.
So I run my util and pipe it to awk, so it returns the WWID and nothing else:
Now I need awk to increment the alphanumeric WWID, so I can add these WWIDs to a host group on my storage enclosures. Here's where my awk-fu is weak. I've tried various things (quotes, etc) but here's a typical example of how far I'm getting:
Is there an economical way to get awk to not choke on the first alpha character it encounters?
I have a utility that shows me the WWID of the first port of a dual port HBA card. The second port is not explicitly listed, however it is always one digit higher than the first.
So, given that port a = 500062b0000eb5a4 -- then I know port b = 500062b0000eb5a5.
So I run my util and pipe it to awk, so it returns the WWID and nothing else:
# ./util | awk '/WWID/ {print $3}'
500062b0000eb5a4
Now I need awk to increment the alphanumeric WWID, so I can add these WWIDs to a host group on my storage enclosures. Here's where my awk-fu is weak. I've tried various things (quotes, etc) but here's a typical example of how far I'm getting:
#./util | awk '/WWID/ {print $3++}'
500063
Is there an economical way to get awk to not choke on the first alpha character it encounters?
Response by poster: Thanks Jeb for the fast reply. How would I express that?
posted by edverb at 7:06 PM on February 5, 2009
posted by edverb at 7:06 PM on February 5, 2009
Best answer: Easy with perl:
posted by nicwolff at 7:28 PM on February 5, 2009
./util | perl -lane '/WWID/ and printf "%x\n", hex($F[3]) + 1'
posted by nicwolff at 7:28 PM on February 5, 2009
Response by poster: Nicwolff, that returns
I should specify, the search string should really be /SAS WWID/, otherwise it's possible my util will return the wrong WWID (I don't want the enclosure or the switches, for example...just my daughter card.)
Any thoughts?
posted by edverb at 8:07 PM on February 5, 2009
integer overflow in hexadecimal number at -e line 1, <> line 26,
ffffffff
>
I should specify, the search string should really be /SAS WWID/, otherwise it's possible my util will return the wrong WWID (I don't want the enclosure or the switches, for example...just my daughter card.)
Any thoughts?
posted by edverb at 8:07 PM on February 5, 2009
sounds like your number is too big for the perl number type. You might have to do something like
posted by jeb at 8:24 PM on February 5, 2009
./util | perl -lane '/SAS WWID/ and print f "%x\n", Math::BigInt->as_hex(Math::BigInt->from_hex($F[3]) + 1)'
posted by jeb at 8:24 PM on February 5, 2009
I tried this with the stock
However, when using
If you can upgrade from the stock
posted by Blazecock Pileon at 9:42 PM on February 5, 2009
bash
and awk
utils:$ hex=500062b0000eb5a4; echo $((16#$hex+1)) | awk '{printf "%x\n", $1;}' -
ffffffff
However, when using
gawk
3.1.5 (GNU awk):$ hex=500062b0000eb5a4; echo $((16#$hex+1)) | gawk '{printf "%x\n", $1;}' -
500062b0000eb400
If you can upgrade from the stock
awk
to the GNU awk
, I bet this will work for you.posted by Blazecock Pileon at 9:42 PM on February 5, 2009
Never mind, that's not right, either.
posted by Blazecock Pileon at 9:42 PM on February 5, 2009
posted by Blazecock Pileon at 9:42 PM on February 5, 2009
Best answer: Looks like awk runs with 32-bit precision even when compiled as 64-bit.
Anyway, here's an awk-less option:
posted by Blazecock Pileon at 9:50 PM on February 5, 2009
Anyway, here's an awk-less option:
$ hex=500062b0000eb5a4; incrementedDec=$((16#$hex+1)); echo "ibase=10;obase=16;$incrementedDec" | bc
500062B0000EB5A5
posted by Blazecock Pileon at 9:50 PM on February 5, 2009
Best answer: All this high-precision and bigint stuff might not be needed. Given you're looking at a two port problem you can probably assume that you won't roll more than one digit. Split off the last four digits to be safe, increment those, and merge back together.
./util | perl -lane '/WWID/ and printf "%s%x\n", substr($F[3],0,-4), hex(substr($F[3],-4)) + 1'
*also, fwiw, nicwolffs solution works under solaris 64bit*
posted by devbrain at 6:51 AM on February 6, 2009
./util | perl -lane '/WWID/ and printf "%s%x\n", substr($F[3],0,-4), hex(substr($F[3],-4)) + 1'
*also, fwiw, nicwolffs solution works under solaris 64bit*
posted by devbrain at 6:51 AM on February 6, 2009
@devbrain i was thinking that splitting idea too but there's a possibility of overflowing the split part, right? i mean as unlikely as it is what if the port number was 500062b0000effff ? then if you'd split off the last four digits you'd miss rolling over the 0 to a 1.
posted by jeb at 8:38 AM on February 6, 2009
posted by jeb at 8:38 AM on February 6, 2009
@jeb: exactly -- if it WAS ffff then this would happen. Given that the application is a two port HBA (I wrote problem when I meant HBA in my first post), I've never seen one with the number of the first on the upper boundary like that.
I'd be surprised to find one with the last two digits of "f", let alone the last 4.
posted by devbrain at 12:25 PM on February 6, 2009
I'd be surprised to find one with the last two digits of "f", let alone the last 4.
posted by devbrain at 12:25 PM on February 6, 2009
ahhh carry on then. i have literally no idea what a two-port hba is. seriously. i'm going to google it after this cause i'm curious.
posted by jeb at 1:28 PM on February 6, 2009
posted by jeb at 1:28 PM on February 6, 2009
Hmm, yeah, mine only works on a 64-bit machine. Sorry 'bout that.
posted by nicwolff at 3:53 PM on February 6, 2009
posted by nicwolff at 3:53 PM on February 6, 2009
Response by poster: devbrain's solution works perfectly, so that's the one I'm going with. Thanks for all of the help everyone!
jeb, here's the dual port SAS HBA (Host Bus Adapter) at issue. It is a single daughter card for blades which gives the host redundant connections to redundant SAS switches, which in turn connect to an external SAS storage enclosure (in this case, DS3200.)
Thanks again all!
posted by edverb at 6:01 PM on February 6, 2009
jeb, here's the dual port SAS HBA (Host Bus Adapter) at issue. It is a single daughter card for blades which gives the host redundant connections to redundant SAS switches, which in turn connect to an external SAS storage enclosure (in this case, DS3200.)
Thanks again all!
posted by edverb at 6:01 PM on February 6, 2009
« Older Fun interesting things to do around Pisma Beach? | May my luggage never grow musty or worn... Newer »
This thread is closed to new comments.
disclaimer: i know nothing about awk, but i mean...all these tools can convert a base-16 string to a number and print a number in base-16 right?
posted by jeb at 6:48 PM on February 5, 2009