使用按位运算符对文件列表的每个数字进行位掩码的有效方法

Efficient way to bit mask every number of a file list using bitwise operators

我有一个文件,其中包含定义如下的数字列表:

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

我想写这样的东西:

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"

它 returns :

80000002
var2 var9 var11 var12 var14 var17

但是,在这种特定情况下,我只想 return :

var21 var2

其他例子,如果 decValue=12288 我想 return var11 和 var12。

按位运算符是解决这个问题的好工具?

使用

printf -v hexValue "%#x" "${decValue}"

(或在循环内的test中使用${decimalValue}

就像现在一样,$hexValue 最终成为 80000002(如您自己的 echo 语句所示),稍后当您需要时将其解释为十进制数被解释为十六进制。

%#x 作为格式说明符传递给 printf 将使 $hexValue 具有值 0x80000002

你还得再好好看看 var table;其中有许多差距。 var2var3 之间缺少 0x4var3var4 之间以及 var17 和 [= 之间缺少 0x10 29=],从 0x800000x8000000 的整个块也不见了。对于设置了这些位的变量,您不会得到预期的结果。

还值得考虑动态生成位掩码,而不是将它们预先计算在文件中。一种可能的方法是

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

在此,位移表达式1 << i给出数字2i,或者换句话说:1 << i与[=34的值相同=] 会修复 table.

或使用perl作为:

perl -F= -slnE 'say $_ if( hex($F[1]) & $num )' -- -num=12288 < file

打印:

var11=0x000001000
var12=0x000002000

perl -F= -slnE 'say $F[0] if( hex($F[1]) & $num )' -- -num=12288 < file

打印

var11
var12