I am creating a script converting a csv file in an another format.
To do so, i need my numbers to have a fixed format to respect column size : 00000000000000000,00 (20 characters, 2 digits after comma)
I have tried to format the number with -f and the method $value.toString("#################.##") without success
Here is an example Input :
4000000
45817,43
400000
570425,02
15864155,69
1068635,69
128586256,9
8901900,04
29393,88
126858346,88
1190011,46
2358411,95
139594,82
13929,74
11516,85
55742,78
96722,57
21408,86
717,01
54930,49
391,13
2118,64
Any hints are welcome :)
Thank you !
tl;dr:
Use 0 instead of # in the format string:
PS> $value = 128586256.9; $value.ToString('00000000000000000000.00')
00000000000128586256.90
Note:
Alternatively, you could construct the format string as an expression:
$value.ToString('0' * 20 + '.00')
The resulting string reflects the current culture with respect to the decimal mark; e.g., with fr-FR (French) in effect, , rather than . would be used; you can pass a specific [cultureinfo] object as the second argument to control what culture is used for formatting; see the docs.
As in your question, I'm assuming that $value already contains a number, which implies that you've already converted the CSV column values - which are invariably strings - to numbers.
To convert a string culture-sensitively to a number, use [double]::Parse('1,2'), for instance (this method too has an overload that allows specifying what culture to use).
Caveat: By contrast, a PowerShell cast (e.g. [double] '1.2') is by design always culture-invariant and only recognizes . as the decimal mark, irrespective of the culture currently in effect.
zerocukor287 has provided the crucial pointer:
To unconditionally represent a digit in a formatted string and default to 0 in the absence of an available digit, use 0, the zero placeholder in a .NET custom numeric format string
By contrast, #, the digit placeholder, represents only digits actually present in the input number.
To illustrate the difference:
PS> (9.1).ToString('.##')
9.1 # only 1 decimal place available, nothing is output for the missing 2nd
PS> (9.1).ToString('.00')
9.10 # only 1 decimal place available, 0 is output for the missing 2nd
Since your input uses commas as decimal point, you can split on the comma and format the whole number and the decimal part separately.
Something like this:
$csv = #'
Item;Price
Item1;4000000
Item2;45817,43
Item3;400000
Item4;570425,02
Item5;15864155,69
Item6;1068635,69
Item7;128586256,9
Item8;8901900,04
Item9;29393,88
Item10;126858346,88
Item11;1190011,46
Item12;2358411,95
Item13;139594,82
Item14;13929,74
Item15;11516,85
Item16;55742,78
Item17;96722,57
Item18;21408,86
Item19;717,01
Item20;54930,49
Item21;391,13
Item22;2118,64
'# | ConvertFrom-Csv -Delimiter ';'
foreach ($item in $csv) {
$num,$dec = $item.Price -split ','
$item.Price = '{0:D20},{1:D2}' -f [int64]$num, [int]$dec
}
# show on screen
$csv
# output to (new) csv file
$csv | Export-Csv -Path 'D:\Test\formatted.csv' -Delimiter ';'
Output in screen:
Item Price
---- -----
Item1 00000000000004000000,00
Item2 00000000000000045817,43
Item3 00000000000000400000,00
Item4 00000000000000570425,02
Item5 00000000000015864155,69
Item6 00000000000001068635,69
Item7 00000000000128586256,09
Item8 00000000000008901900,04
Item9 00000000000000029393,88
Item10 00000000000126858346,88
Item11 00000000000001190011,46
Item12 00000000000002358411,95
Item13 00000000000000139594,82
Item14 00000000000000013929,74
Item15 00000000000000011516,85
Item16 00000000000000055742,78
Item17 00000000000000096722,57
Item18 00000000000000021408,86
Item19 00000000000000000717,01
Item20 00000000000000054930,49
Item21 00000000000000000391,13
Item22 00000000000000002118,64
I do things like this all the time, usually for generating computernames. That custom numeric format string reference will come in handy. If you want a literal period, you have to backslash it.
1..5 | % tostring 00000000000000000000.00
00000000000000000001.00
00000000000000000002.00
00000000000000000003.00
00000000000000000004.00
00000000000000000005.00
Adding commas to long numbers:
psdrive c | % free | % tostring '0,0' # or '#,#'
18,272,501,760
"Per mille" character ‰ :
.00354 | % tostring '#0.##‰'
3.54‰
How can I treat a string which is a hexadecimal number as a hexadecimal number? For example, I am loading in a file of hexadecimal numbers but Python is loading the file in as a string. Is it possible to get Powershell to treat the hexadecimal numbers in the file as hexadecimal numbers?
Background: I'm asking the user for a Mac Address and I need to add x numbers to the last block to get the next x Mac addresses. I can split on ":" and get the last block but this is a string containing for example "13", which is not 13 decimal but 13 hex.
Try converting it first to an int by casting the variable with the base 16 as the second argument
hex_str = "0xAD4"
hex_int = int(hex_str, 16)
then just add 1 to the result and use
hex(hex_int)
to get the result back to hex format
Just the whole MAC address in once by using the PhysicalAddress.Parse(String) Method:
$MAC = 'F0:E1:D2:C3:B4:A5' -Replace '[^0-9a-fA-F]' # remove all the non-Hex characters
[System.Net.NetworkInformation.PhysicalAddress]::Parse($MAC).GetAddressBytes()
240
225
210
195
180
165
Solved it by doing it like this:
$MacNr = ([int64]"0x$($MacAddress.Split(":")[5])")
$MacNr ++1
$NewMac = ('{0:X2}' -f $MacNr)
I'm trying to create a string from hex values in an array, but whenever a hex in the array starts with a zero it disappears in the resulting string as well.
I use String(value:radix:uppercase) to create the string.
An example:
Here's an array: [0x13245678, 0x12345678, 0x12345678, 0x12345678].
Which gives me the string: 12345678123456781234567812345678 (32 characters)
But the following array: [0x02345678, 0x12345678, 0x02345678, 0x12345678] (notice that I replaced two 1's with zeroes).
Gives me the string: 234567812345678234567812345678 (30 characters)
I'm not sure why it removes the zeroes. I know the value is correct; how can I format it to keep the zero if it was there?
The number 0x01234567 is really just 0x1234567. Leading zeros in number literals don't mean anything (unless you are using the leading 0 for octal number literals).
Instead of using String(value:radix:uppercase), use String(format:).
let num = 0x1234567
let str = String(format: "%08X", num)
Explanation of the format:
The 0 means to pad the left end of the string with zeros as needed.
The 8 means you want the result to be 8 characters long
The X means you want the number converted to uppercase hex. Use x if you want lowercase hex.
I am looking to generate a list of hex values using Powershell. For instance, [0..100] creates an array of numbers 0-100.
How would I go about creating an array of values from 000-FFF?
You can use following expression:
0..0xfff|% ToString X3
Where:
0 is zero.
.. is range operator.
0xfff is integer literal for 4095 in hexadecimal form.
| is pipe operator.
% is alias for ForEach-Object cmdlet.
ToString is name of method to call.
X3 is parameter for method. It is standard numeric format string that means, format as hexadecimal number with at least three digits.
So:
0..0xfff creates an array of numbers 0-4095.
| pass elements of array to next command.
% ToString X3 format each number as hexadecimal with at least three digits.
Is there a format string to truncate a number to a specific number of digits?
For example, any number greater than 5 digits i would like to truncate to 3 digits.
132456 -> 132
5000000 -> 500
#Erik : Format specifiers like %2d are specific to a language? I actually want to use it in javascript
Pseudo-Code
Function returning a String, receiving a String representing a Number as a parameter
IF the String has more than 5 characters
RETURN a substring containing the first 3 characters.
ELSE
RETURN the string received as a parameter
END IF
END Function
I assume you refer to printf format strings. I couldn't find anything that will truncate an integer argument (i.e. %d). But you can specify the maximum length of a string by referring to a string format string and specifying lengths via "%<MinLength>.<MaxLength>s".
So in your case you could turn your number arguments into strings and then use "%3.3s".