Unformat Size Strings

Is there a way to convert strings like 1K to 1000 , 1M to 1000000 , etc. with a single bash command? I would like to avoid becoming a millionaire and the thirty-first guy to create a> 10-line or> 100-character single-line hack for this. Something like iso2int 5MB .

Edit: units -t '5MB' 'bytes works, but this tool is not available. Are there any simple ways to convert either 5M or 5MB and are similar to bytes?

Decision

max was elegant, but the shortest equivalent that would work in my case is at least sed -e 's/b//i;s/k/*1000/i;s/m/*1000000/i;s/g/*1000000000/i;s/t/*1000000000000/i' | bc sed -e 's/b//i;s/k/*1000/i;s/m/*1000000/i;s/g/*1000000000/i;s/t/*1000000000000/i' | bc .

+3
source share
2 answers

Something like that?

 $ echo "1K + 10M" | sed -e "s/K/*1024/g;s/M/*1024*1024/" | bc 10486784 

Edit:

 sed -e 's/t/kg/i;s/g/km/i;s/m/kk/i;s/k/*1000/ig;s/b//i' | bc 
+3
source

Edit:

My original answer is simply stupid . Here is a clean bash solution based on max taldykin sed / bc excellent answer .

 s=21TB;(( $BASH_VERSINFO >= 4 ))&&s=${s^^};s=${s/B};s=${s/E/KP};s=${s/P/KT}; s=${s/T/KG};s=${s/G/KM};s=${s/M/KK};s=${s//K/*1024};printf "%'u\n" $((s)) 

This is more than my original single-line font, only due to the fact that it includes case insensitivity, while the latter did not (although it could and did). This is approximately twice the size of the character specified as max when configured for equivalent functionality.

Original:

Here is a clean Bash solution:

As a function (see below for single line):

 #!/bin/bash # written by Dennis Williamson 2010-12-09 # for https://stackoverflow.com/questions/4399475/unformat-disk-size-strings expandsi () { # set k to 1000 if that your preference, p is a pattern to match unit chars local k=1024 p='E|P|T|G|M|K| ' # exa, peta, tera, giga, mega, kilo, bytes local b=$1 ces=${p//|} # s is the list of units (( $BASH_VERSINFO >= 4 )) && b=${b^^} # toupper for case insensitivity b=${b%B*} # strip any trailing B from the input c=${b: -1} # get the unit character c=${c/%!($p)/ } # add a space if there no unit char b=${b%@($p)*} # remove the unit character e=${s#*${c:0:1}} # index into the list of units # do the math, remove the single quote to omit the thousands separator printf "%'u\n" $((b * k**${#e})) } 

To test a function:

 testvals='1 22 333 4444 ' testvals+='4B 44B 1000B ' testvals+='1M 1MB 987MB ' testvals+='1K 23KB 1KB 100K ' testvals+='10G 10GB 3333G ' testvals+='3T 12PB ' # exabytes is pushing it for Bash int capacity # on my system, printf "%'u\n" -1 gives 18,446,744,073,709,551,615 testvals+='15EB ' for i in $testvals do expandsi $i done 

Results:

 1 22 333 4,444 4 44 1,000 1,048,576 1,048,576 1,034,944,512 1,024 23,552 1,024 102,400 10,737,418,240 10,737,418,240 3,578,781,499,392 3,298,534,883,328 13,510,798,882,111,488 17,293,822,569,102,704,640 

As promised, in the end, a one-line option:

 $ b=200GB k=1024 p='E|P|T|G|M|K| ';s=${p//|} b=${b%B*};c=${b: -1};c=${c/%!($p)/ };b=${b%@($p)*};e=${s#*${c:0:1}};printf "%'u\n" $((b * k**${#e})) 214,748,364,800 
+1
source

Source: https://habr.com/ru/post/1205744/


All Articles