我想知道是否有办法用if检查$2
是否将第7位设置为1来替换if语句?
cat $file | awk '{if ($2 == 87) print $1; else {}}' > out.txt"
例如,93应该打印一些东西而128不应该打印。
答案 0 :(得分:5)
bash有按位运算符
测试第7位:
$ echo $(((93 & 0x40) != 0))
1
$ echo $(((128 & 0x40) != 0))
0
虽然如果你正在从文件中解析这些值,你最好继续使用awk,作为@RakholiyaJenish的答案
答案 1 :(得分:3)
您可以使用按位运算来检查1
中第7位是gawk
:
and($2,0x40)
注意:标准awk
没有按位操作。因此,您可以使用bash
按位运算或perl
按位运算(用于字符串处理)。
使用gawk
:
gawk '(and($2,0x40)){print $1}' filename
使用perl
:
perl -ane 'print "$F[0]\n" if ($F[1]&0x40)' filename
答案 2 :(得分:2)
您可以使用bash
包装函数检查位集,在脚本中定义本地IFS
运算符或.bashrc
# Returns the bit positions set in the number for the given bit mask
# Use the return value of the function directly in a script
bitWiseAnd() {
local IFS='&'
printf "%s\n" "$(( $* ))"
}
并在脚本中的函数中使用它
# The arguments to this function should be used as number and bit-mask, i.e.
# bitWiseAnd <number> <bit-mask>
if [ $(bitWiseAnd "93" "0x40") -ne 0 ]
then
# other script actions go here
echo "Bit set"
fi
这个想法是使用Input-Field-Separator(IFS),bash
中的一个特殊变量,用于扩展后的单词拆分,并将行拆分为单词。该函数在本地更改值以使用分词字符作为按位AND
运算符&
。
请记住IFS
在本地更改,并且 NOT 对函数范围之外的默认IFS
行为生效。摘自man bash
页面,
shell将IFS的每个字符视为分隔符,并将其他扩展的结果拆分为这些字符上的单词。如果未设置IFS,或者其值正好是默认值,则会忽略先前扩展结果的开始和结束的,以及序列,并且不在开头或结尾的任何IFS字符序列用于分隔话。
"$(( $* ))"
表示传递给&
的参数列表,稍后使用printf
函数输出计算值。该函数可以扩展为其他算术运算添加范围。
答案 3 :(得分:0)
如果作为第一个参数给出的数字作为第二个参数集给出,则此函数返回退出状态为零:
hasbitset () {
local num=$1
local bit=$2
if (( num & 2**(bit-1) )); then
return 0
else
return 1
fi
}
或简短且不易阅读:
hasbitset () { (( $1 & 2**($2-1) )) && return 0 || return 1; }
对于问题的例子:
$ hasbitset 93 7 && echo "Yes" || echo "No"
Yes
$ hasbitset 128 7 && echo "Yes" || echo "No"
No
请注意,通常习惯于计算偏移中的位而不是位数,即从位0开始 - 与此问题中的用法不同。