1

In CPP, we could use apostrophes to delimit digits for better readability: 1'000'000. Same for underscores in Python: 1_000_000.

How could we do that in Bash, for a=1000000?

This is not about the printed output.

Zack Light
  • 167
  • 2
  • 11
  • 1
    bash does not have the data type "number". It can only handle strings (and arrays of strings), so it depends on where/how you use your variable `a`. bash itself can do some integer arithmetic, and if you evaluate a variable in numeric context (for instance `echo $((a))`, you must not have some funny characters between the digits. For completeness: If you would use zsh, the underscore could indeed be used in numeric context (plus you could numbers with a decimal point too!). If you consider this feature important, perhaps implementing the script in zsh would be an alternative. – user1934428 Apr 21 '23 at 06:01
  • @user1934428 that makes sense. I vaguely remembered having used delimiters in bash/zsh before. – Zack Light Apr 22 '23 at 01:39
  • With bash, I don't think so. If they ever had such a feature, this would still exist in present day's bash (for upward compatibility). BTW, you find everything you need to know about numeric context in the bash man-page, section _ARITHMETIC EVALUATION_. This section is pretty short, and it is worth reading. – user1934428 Apr 23 '23 at 09:20

2 Answers2

1

One way:

a='1''000''000'
$ echo $a
1000000

This is a simple concatenation. AFAIK, there's no built-in to do that.

One other way, using parameter expansion:

$ a='1_000_000'
$ a=${a//_/}
$ echo $a
1000000
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • ok... Now I wonder if zsh has a good way. – Zack Light Apr 20 '23 at 14:21
  • 2
    @ZackLight, so, part of the problem here is that shells mostly don't have integer types at all (`declare -i` and the like exists, but there are often valid/compelling reasons to stay clear); and if you don't know something isn't an integer, you don't know that your `_` or other placeholder isn't actually part of the string itself. That's why one ends up with `'1''000''000'` -- it's completely normal string syntax, not a number-specific extension. – Charles Duffy Apr 20 '23 at 14:32
1

For a literal, there are options, but not really any great ones.

You say

This is not about the printed output.

but for some folk it will be, so I will reference this other post about that, and move on.

Giles suggested quotes, which work, but aren't lovely. On that note, I'd like to point out that your own example of 1'000'000 will in fact work just fine; it just puts quotes around the three zeroes in the middle, which when evaluated changes nothing, so it looks fine and has no impact, but is likely to confuse someone reading it later... and in the case of 1'000'000'000 or any other odd number of single ticks, it fails because of unclosed quotes.

You can go halfway between - instead of Giles' quotes around each block, just open and close a pair of quotes between each section, embedding nothing: a=1''000''000. This eliminates the need for leading and training quotes, but is still ugly.

Another trick you might try is a single-character backslash.

$: a=1\000\000
$: echo $((a/1000))
1000

This escapes the literal digit it precedes, but can be more dangerous, depending on your context, as in some situations it is treated differently.

Obviously, quotes throw caveats on all these, as they will include the "delimiter" characters in the data, which really isn't what you want.

$: a=1\000    ; echo $a # fine, the first zero quoted during assignment
1000
$: a="1\000"  ; echo $a # nope, includes the slash
1\000
$: a=$"1\000" ; echo $a # nope, slash again
1\000
$: a=$'1\000' ; echo $a # BIG nope - includes a NULL byte
1
Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
  • `a=1''000''000` looks good enough :) – Zack Light Apr 20 '23 at 15:25
  • 1
    @ZackLight : But don't forget that this would not work in numeric context, i.e. `echo $((5*1''000''000))` would produce a syntax error. – user1934428 Apr 21 '23 at 06:05
  • Same for the backslashes. They force a character to be THAT CHARACTER in most contexts, rather than part of a number. Only use this stuff for standalone assignments and such, and always test. – Paul Hodges Apr 21 '23 at 14:33