使用按位运算符对文件列表的每个数字进行位掩码的有效方法
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;其中有许多差距。 var2
和 var3
之间缺少 0x4
,var3
和 var4
之间以及 var17
和 [= 之间缺少 0x10
29=],从 0x80000
到 0x8000000
的整个块也不见了。对于设置了这些位的变量,您不会得到预期的结果。
还值得考虑动态生成位掩码,而不是将它们预先计算在文件中。一种可能的方法是
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
我有一个文件,其中包含定义如下的数字列表:
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;其中有许多差距。 var2
和 var3
之间缺少 0x4
,var3
和 var4
之间以及 var17
和 [= 之间缺少 0x10
29=],从 0x80000
到 0x8000000
的整个块也不见了。对于设置了这些位的变量,您不会得到预期的结果。
还值得考虑动态生成位掩码,而不是将它们预先计算在文件中。一种可能的方法是
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