繁体   English   中英

awk BEGIN比较if语句中的多个变量

[英]awk BEGIN compare multiple variables in if statement

我正在尝试比较bash的一些浮点数/版本号,为此我将awk BEGIN与if语句一起使用。 当我使用2个变量时,我能够进行比较并获得正确的输出。 但是在3个变量的情况下,我无法获得输出。

目的

我要实现的是,如果输入介于两个值4.8.0和4.10.0之间(即4.8.0 <= inp <4.10.0 ),则输出1,否则输出0。

代码块

以下是我写的内容:

inp=4.9.4
out=`awk -v n1=$inp -v n2=4.8.0 -v n3=4.10.0 \
  'BEGIN {if (n1<n2) printf (0); else if (n1<n3) printf (1); else printf (0);}'`

我尝试的另一种方法是与多个条件进行比较

inp=4.9.4
out=`awk -v n1=$inp -v n2=4.8.0 -v n3=4.10.0 \
  'BEGIN {if (n1>n2 && n1<n3) printf (1); else printf (0);}'`

查询 :请帮助我如何使用awk BEGIN实现相同的目标? 另外,如果还有其他方法可以比较浮点输入?

如果您的sort支持版本排序,则可以使用以下快速机制:

if [ $(printf "%s\n" 4.8.0 "$inp" 4.10.0 | sort -V | awk NR==2 ) == "$inp" ]; then
    : Do something
fi

问题不在于“ <”本身,而是字符串比较元素4.9大于4.10(字符串角度)。 在这种情况下,您必须将4.09与4.10进行比较,因此将输入转换为相同的比较顺序,这取决于您的版本控制上下文

inp=4.9.0
out = $(
 awk -v nt=${inp} -v nl=4.8.0 -v nh=4.10.0 \
  '# use a function to compare dotted value 
    function lt( Arg1, Arg2) {
      # split version into elements
      S = ES1 = split( Arg1, E1, /[.]/)
      ES2 = split( Arg2, E2, /[.]/)
      # take longest serie
      if( ES1 < ES2) S = ES2
      # reinit lower and bigger flag
      l=b=0

      # test if bigger, smaller or equivalent
      for( i=1;i <= S && ! ( l || b ) ; i++) {
         if( E1[i] < E2[i] ) l++
          else if ( E1[i] > E2[i] ) b++
         }
      # return 1 if smaller
      return ( l )
      }

   # is between
   BEGIN { print ( lt(nl, nt) && lt( nt, nh)) }
   '
   )

注意:

  • 分割点元素的函数,将数字尽可能地与数字进行比较
  • 更长或更短的版本号也将进行比较(空等效元素被视为0)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM