I have a macro that implements a conversion algorithm. At one point in that algorithm I have to add leading zeros to make sure that a hex value has 8 digits, and not less.
What I've done is a little clunky, and it only zeropads from 7 digits to 8, but in my particular case it's sufficient:
eval myInt=if(len(myInt)==7,"0".myInt,myInt)
Anyone have any suggestions? I see that eval does not have anything obvious here like a zeropad
function. I wonder if it would be a good thing to add, or if there's some other way of doing this more cleanly, or in such a way that it can add the correct number of zeros and not just one, with eval or with another command. Any help appreciated.
How about
* | eval myInt="00000000000".tostring(myInt) | eval length=len(tostring(myInt)) | eval trimLength=tonumber(length-3) | eval myInt=tonumber(substr(myInt,trimLength))
There may be some small errors in there as I haven't had the time to test that. In essence, it prepends a bunch of zeros, finds the difference between the length of the string with all the zeros and the total length you want (I chose 3 in the example), and then uses substr() to return only that many digits from the right end of the string.
Using printf
conversion function this is possible using something like printf("%04d",fieldName)
. Refer to documentation: https://docs.splunk.com/Documentation/Splunk/latest/SearchReference/ConversionFunctions#Flag_charact...
Following is a run anywhere example:
| makeresults
| fields - _time
| eval data=1
| eval padded_data= printf("%04d",data)
Assuming I know the numbers are always positive and below a certain length, I use a SUBSTR function. For example, to pad out to a 4-digit value
eval formattedNumber=substr("0000".rawNumber,-4)
This worked perfect for me!
I think the "most correct" option (which does not exist btw) would be a printf-like printed-format function - something like...
| eval newfield=printf("%04.4f %-30s",fieldone, fieldtwo)
I filed an ER asking for this earlier this year - case # 113961. Feel free to tack on a "me too" ER case.
Good news: this eval function was added in Splunk 6.6 (released today)
Thanks Mitch and all the other Splunkers.
I downvoted this post because it is not a solution, its a would be nice if this works
We don't usually downvote for items like this, saving downvoting for things that are plainly wrong or might break people's systems. This forum is intended as a place to share and communicate various solutions, and occasionally 'Yes, I filed an enhancement request for this, please join it' is sometimes completely valid.
Yes, that looks closest to a "zerofill" function, or "format" function or something. I don't think I filed an ER.
How about this - keeps it simple. Use eval
to tack on as many zeroes as you'll ever need, then rex
to get the last x amount of digits.
Regular
... | eval myint="000000".myint | rex field=myint "(?<myint>\d{6})$"
Hex
... | eval myhex="00000000".myhex | rex field=myhex "(?<myhex>[0-9A-Fa-f]{8})$"
How about
* | eval myInt="00000000000".tostring(myInt) | eval length=len(tostring(myInt)) | eval trimLength=tonumber(length-3) | eval myInt=tonumber(substr(myInt,trimLength))
There may be some small errors in there as I haven't had the time to test that. In essence, it prepends a bunch of zeros, finds the difference between the length of the string with all the zeros and the total length you want (I chose 3 in the example), and then uses substr() to return only that many digits from the right end of the string.
Not bad. #1) - the 'tonumber' on the end ends up removing all the hard-earned zeros. #2), in my case my values are in hex so I can't use any of the int() stuff.
However you're close. This is similar and works very well.
| eval myVal="1A09" | eval initialLength=len(tostring(myVal)) | eval myVal="0000000000".tostring(myVal) | eval myVal=substr(myVal,initialLength,10)
You can use rex to first pad the number with "enough" zeroes, then to trim it to the length you require. I broke it into two parts since rex's sed mode doesn't seem to like concatenated commands; I don't know whether you consider this cleaner, but it does allow for variable-length numbers. Let me know if this is useful.
... | rex mode=sed field=myInt "s/(\d+)/00000000\1/" | rex mode=sed field=myInt "s/0*([0-9]{8})/\1/"
Awesome. No, I like that better than mine. I'll leave the question open for another couple days in case someone has a third way.