I have a file which contains a list of numbers defined as follow :
var1=0x00000001
var2=0x00000002
var3=0x00000008
var4=0x00000020
var5=0x00000040
var6=0x00000080
var7=0x00000100
var8=0x00000200
var9=0x00000400
var10=0x00000800
var11=0x000001000
var12=0x000002000
var13=0x000004000
var14=0x000008000
var15=0x00010000
var16=0x00020000
var17=0x00040000
var18=0x10000000
var19=0x20000000
var20=0x40000000
var21=0x80000000
I want to write something like this:
decValue=2147483650
printf -v hexValue "%x" "${decValue}"
echo $hexValue
IFS="="
while read name ID x
do
test $((${hexValue} & ${ID})) = 0 && continue
array+=("${name}")
done < "$FILE_NAME"
It returns :
80000002
var2 var9 var11 var12 var14 var17
But, in this specific case I just would like to return :
var21 var2
Other example, if decValue=12288 I would like to return var11 and var12.
Bitwise operators is a good tool to solve this issue ?
Use
printf -v hexValue "%#x" "${decValue}"
(or use ${decimalValue}
in the test
inside the loop)
As it is now, $hexValue
ends up being 80000002
(as your own echo
statement shows), and this is later interpreted as a decimal number when you want it to be interpreted as a hexadeximal one.
Passing %#x
as format specifier to printf
will make $hexValue
have the value 0x80000002
.
You'll also have to take another good look at the var
table; there are a number of gaps in it. 0x4
is missing between var2
and var3
, 0x10
is missing between var3
and var4
, and between var17
and var18
, the whole block from 0x80000
to 0x8000000
is gone as well. You're not going to get the results you expect for variables that have any of these bits set.
It might also be worth a thought to generate the bitmasks on the fly rather than holding them precalcuated in a file. One possible approach for that is
for((i = 0; (1 << i) <= $hexValue; ++i))
do
test $(($hexValue & (1 << i))) = 0 && continue
# Note: this will remember (zero-based) bit numbers rather than variable
# names because there are no named variables any longer
array+=($i)
done
In this, the bitshift expression 1 << i
gives the number 2i, or put another way: 1 << i
has the same value as var$((i + 1))
would in a repaired table.
Or use perl
as:
perl -F= -slnE 'say $_ if( hex($F[1]) & $num )' -- -num=12288 < file
prints:
var11=0x000001000
var12=0x000002000
or
perl -F= -slnE 'say $F[0] if( hex($F[1]) & $num )' -- -num=12288 < file
prints
var11
var12
User contributions licensed under CC BY-SA 3.0