TIL: looping over hex numbers in Bash
Sometimes we need hexadecimal numbers. Sometimes we need to loop over them. And sometimes we need to do that in Bash.
![Chevrolet El Camino?](https://live.staticflickr.com/65535/53671856349_47a684817e_c.jpg)
We are talking about Bash, so it only takes one line to do it. For example, to
go from 8
to 0xe
(not inclusive), and print the decimal value and their hex
number:
for ((i = 8; i < $(printf %d 0xe); ++i)); do j=$(printf "%x" $i); echo -e "$i:\t $j"; done
8: 8
9: 9
10: a
11: b
12: c
13: d
Now, let’s see bit by bit what is this one-liner. The same code, in multiple lines, for educational purposes only:
for ((i = 8; i < $(printf "%d" 0xe); ++i)); do
j=$(printf "%x" $i)
echo -e "$i:\t $j"
done
The first line is a C-style for
loop. The loop variable, i
, starts from 8
and the loop goes on while i < $(printf "%d" 0xe)
is true. The loop variable
is incremented (++i
, C-style pre-increment) at the end of each iteration.
The printf "%d" 0xe
is the cool trick: it takes the string 0xe
and
generates another string using the formatter %d
. This means: print 0xe as
an integer. This way the loop starts at 8 and ends at 14 (0xe), not
inclusive. The printf
is executed using
command substitution,
so its value “replaces” the command. This is what “tricks” the for loop into
starting from 0 and ending at 13.
As the loop is not inclusive (the condition is i < 14
), the last iteration
happens with i=13
.
The second printf
does the opposite: takes the variable i
, prints as
hexadecimal (formatter %x
is for hexadecimal numbers) and “saves” it as the
variable j
. The echo
statement prints i
, the decimal value, and j
, the
corresponding hexadecimal.
All one needs when coding in Bash is one line.
And just for fun, here’s the equivalent Python code:
for i in range(0, 0xE):
print(f"{i}: {i:x}")
But why use Python when we can suffer with Bash?