Splunk Search

is there a cleaner way to zeropad numeric values, ie add leading zeros?

sideview
SplunkTrust
SplunkTrust

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.

Tags (2)
1 Solution

rtadams89
Contributor

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.

View solution in original post

niketn
Legend

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)
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

jhodgepason
Engager

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)

nickbloglovin
Engager

This worked perfect for me!

dwaddle
SplunkTrust
SplunkTrust

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.

mitch_1
Splunk Employee
Splunk Employee

Good news: this eval function was added in Splunk 6.6 (released today)

enno
Explorer

Thanks Mitch and all the other Splunkers.

0 Karma

AdamParuk
New Member

I downvoted this post because it is not a solution, its a would be nice if this works

0 Karma

Richfez
SplunkTrust
SplunkTrust

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.

Jason
Motivator

Yes, that looks closest to a "zerofill" function, or "format" function or something. I don't think I filed an ER.

0 Karma

Jason
Motivator

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})$"

rtadams89
Contributor

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.

sideview
SplunkTrust
SplunkTrust

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)

cphair
Builder

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/"

sideview
SplunkTrust
SplunkTrust

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.

Get Updates on the Splunk Community!

Introducing Splunk Enterprise 9.2

WATCH HERE! Watch this Tech Talk to learn about the latest features and enhancements shipped in the new Splunk ...

Adoption of RUM and APM at Splunk

    Unleash the power of Splunk Observability   Watch Now In this can't miss Tech Talk! The Splunk Growth ...

Routing logs with Splunk OTel Collector for Kubernetes

The Splunk Distribution of the OpenTelemetry (OTel) Collector is a product that provides a way to ingest ...