-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add built in printf function #614
Comments
I definitely think that, given those two choices, a more typical The question becomes how complete do we want this printf to be? I'm going to strongly advise against passing through to sprintf and friends, as I see a security/safety problem there which merits an amount of consideration. The other side of that, though, is that using sprintf and friends means we can support (essentially) full printf specifiers, assuming we can enforce some kind of type safety. That being said, I'm all for this. I just think it should be thought through a bit more. @nicowilliams, @pkoppstein, your thoughts? |
@wtlangford wrote:
Based in part on @nicowilliams emphasis elsewhere on the virtues of composition, I had assumed that the Tao of Jq would lead to a filter along the lines of the proposed Perhaps it's not really an either-or situation, just a question of which comes first? |
A printf would be nice, yes, mostly so as to handle alignment and number formatting options. |
My need is to be able converting integers into hex representation (that is how I came to this issue). Looking forward to see printf in next jq version.. |
Sorry to hijack, but that issue comes up as the "convert to string result", so I decided not to create a new one. Soo how does one currently convert number to string? |
@dolzenko: |
anyone ending up here might want to look at string interpolation, does 99% of what I'd use printf for: https://stedolan.github.io/jq/manual/#Stringinterpolation-\(foo) |
@pbkdf3 look at the example in the first post / issue description - it's mostly about various number conversion/formatting options (decimal/hex/scientific, leading zeros/spaces, decimal places, etc.) |
A proper |
I would like to convert timestamps expressed in milliseconds since the epoch to ISO 8601 strings, with the milliseconds part. jq's built-in time formatting doesn't support milliseconds, so i could use printf, or some more sophisticated string interpolation, to format the milliseconds part, but jq doesn't have that either. One or the other would be really useful! For my own future reference, i ended up with this:
|
Linking to #1341 for further reference. |
I'd already be happy to pad a string with spaces to a specified length. Can't find a function for that and printf should be able to do that. |
@nicowilliams wrote four years ago:
The things I want to use printf for don't seem to be possible with string interpolation, (nor do they strictly require varargs support). $ echo '[94, 172]' | jq -r '.[]' | awk '{$1=sprintf("%3d", $1); print}'
94
172 Or various other printf conversions. Is there some workaround short of filtering through an external tool like awk? |
Padding is easily done using defs such as these:
Certainly having a |
since the string is interpolated when parsed we can't save the 'format' for later use:
this one works...
i tried like this, no luck:
an eval like function would be needed to make interpolation work with a saved 'format' string. |
@lgfausak wrote:
One can "save" a format using a suitable For example: def f($num): "number: ($num)"; |
@lgfausak if you looking for some kind of simpler templating with dynamic strings then i've used something like this: def template($s):
( . as $env
| $s
| gsub("\\{(?<var>.*?)}"; $env[.var])
);
{name: "jq"} | template("hello {name}")
|
I made a module that implements |
As it stands, there is currently little flexibility in how to convert values to a string.
What I would like is a printf-style function that can format a string based on inputs. I'd imagine something like:
printf(format_str) : Takes a list as input and outputs a string. Each element of the list is used as the input to the respective format character. The list must be the correct length.
For example:
["foo", 3.14159, 2.71828] | printf("Hello %5s, your data is %.2f, %d")
would produce
"Hello foo, your data is 3.14, 2"
Another possible option that would work better with the existing string interpolation might be a function that simply does the tostring conversion with a format spec, like
1|format("02d") == "01"
.Then my above example might look more like:
["foo", 3.14159, 2.71828] | "Hello \(.[0]|format("5s")), your data is \(.[1]|format(".2f")), \(.[2]|format("d"))"
The text was updated successfully, but these errors were encountered: