2010-12-09 137 views
3

是否有某種方式將字符串轉換像1K10001M1000000等與單個bash命令?我想避免成爲第一百三十一名創建一個> 10行或者> 100個字符的單線黑客的人。類似於iso2int 5MBUNFORMAT磁盤大小串

編輯:units -t '5MB' 'bytes工程,但該工具不可用。有沒有簡單的方法來轉換或者5M5MB和類似的字節?

最大的解決方案是優雅的,但在我的情況下最短的等效,至少是sed -e 's/b//i;s/k/*1000/i;s/m/*1000000/i;s/g/*1000000000/i;s/t/*1000000000000/i' | bc

+1

http://www.linuxquestions.org/questions/programming-9/perl-vs-bash-code-行數534142/ – Anders 2010-12-09 15:04:18

回答

3

是這樣的嗎?

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

編輯:

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

編輯:

我原來的答覆只是。這是一個基於max taldykin's sed/bc excellent answer的純Bash解決方案。

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)) 

這比我原來的單行不再僅僅憑藉的事實,它包括不區分大小寫,而後者沒有(雖然它可以和功能一樣)。在調整等效功能時,字符數只有max的兩倍。

原件:

這裏是一個純擊溶液:

作爲函數(參見下面的一襯墊):

#!/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's 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 c e s=${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's 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})) 
} 

要測試功能:

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's 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 

結果:

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 

正如所承諾的,終於,在一個班輪版本:

$ 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