The little things give you away... A collection of various small helper stuff
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

79 lignes
1.8 KiB

  1. #!/usr/bin/env python3
  2. # Read file sizes from stdin, print sum on stdout
  3. # Accepted formats on stdin:
  4. # - '1.2 MB', interpreted as 1200000 bytes
  5. # - '1.2 MiB', interpreted as 1.20 * 1024 * 1024 = 1258291.2 bytes
  6. # - '1.2M', interpreted as MiB
  7. # - '123', interpreted as 123 bytes
  8. # Known units: B; kB, MB, GB, TB, PB, EB; KiB, MiB, GiB, TiB, PiB, EiB; K, M, G, T, P, E
  9. # In all cases, whitespace is optional, can be any width, and may contain tabs. Leading and trailing whitespace is also permitted.
  10. # All numbers are cast to an integer before summation.
  11. # Output is by default formatted as IEC (i.e. KiB, MiB, etc.).
  12. import math
  13. import re
  14. import sys
  15. units = {
  16. 'B': 1,
  17. # SI prefixes
  18. 'kB': 1000,
  19. 'MB': 1000**2,
  20. 'GB': 1000**3,
  21. 'TB': 1000**4,
  22. 'PB': 1000**5,
  23. 'EB': 1000**6,
  24. # IEC
  25. 'KiB': 1024,
  26. 'MiB': 1024**2,
  27. 'GiB': 1024**3,
  28. 'TiB': 1024**4,
  29. 'PiB': 1024**5,
  30. 'EiB': 1024**6,
  31. # Short IEC
  32. 'K': 1024,
  33. 'M': 1024**2,
  34. 'G': 1024**3,
  35. 'T': 1024**4,
  36. 'P': 1024**5,
  37. 'E': 1024**6,
  38. }
  39. sum = 0
  40. for line in sys.stdin:
  41. origLine = line.rstrip('\r\n')
  42. line = re.sub(r'\s+', '', line.strip())
  43. line = re.sub(r'([a-zA-Z])', r' \1', line, count = 1)
  44. if ' ' in line:
  45. number, unit = line.split(' ', 1)
  46. else:
  47. number = line
  48. unit = 'B'
  49. if unit not in units:
  50. print(f'Skipping line with unknown unit: {origLine}', file = sys.stderr)
  51. continue
  52. try:
  53. if number.strip('0123456789') == '':
  54. number = int(number)
  55. else:
  56. number = float(number)
  57. except ValueError as e:
  58. print(f'Skipping line with unparseable number: {origLine}', file = sys.stderr)
  59. continue
  60. sum += int(number * units[unit])
  61. # Special case because log(0) is kinda bad...
  62. if sum == 0:
  63. print('0 B')
  64. sys.exit(0)
  65. log = int(math.log(sum if sum > 0 else -sum, 1024))
  66. unit = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'][log]
  67. if unit == 'B':
  68. print(f'{sum} {unit}')
  69. else:
  70. print(f'{sum / 1024**log :.2f} {unit}')