检查bash中是否设置了第n位

时间:2015-07-02 08:35:17

标签: bash awk binary

我想知道是否有办法用if检查$2是否将第7位设置为1来替换if语句?

cat $file | awk '{if ($2 == 87) print $1; else {}}' > out.txt"

例如,93应该打印一些东西而128不应该打印。

4 个答案:

答案 0 :(得分:5)

bash有按位运算符

测试第7位:

$ echo $(((93 & 0x40) != 0))
1

$ echo $(((128 & 0x40) != 0))
0

另请参阅bash documentation

虽然如果你正在从文件中解析这些值,你最好继续使用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开始 - 与此问题中的用法不同。