在每第n次迭代期间执行命令

时间:2014-08-18 14:05:11

标签: bash

我想在每个奇数循环迭代(第一,第三,第五等)中打印“OK”,并且在每个偶数循环迭代(第二,第四,第六等)期间打印“不正常”。我能够通过以下方式实现这一目标:

$ for (( i=0,j=24,k=48; i<=200; i=i+48,j=j+48,k=k+48 )); do printf '%s\n%s\n' ""$i" to "$j" is OK" ""$j" to "$k" is not OK"; done
0 to 24 is OK
24 to 48 is not OK
48 to 72 is OK
72 to 96 is not OK
96 to 120 is OK
120 to 144 is not OK
144 to 168 is OK
168 to 192 is not OK
192 to 216 is OK
216 to 240 is not OK
$ 

然而,是否有更优雅的解决方案来实现同样的目标?

6 个答案:

答案 0 :(得分:5)

您可以使用modulo运算符%

for (( i=0; i<200; i+=24 )); do
  echo -n "$i to $((i+24)) is "
  ((i % 48 != 0)) && echo -n "not "
  echo OK
done

答案 1 :(得分:2)

此代码将输出与您相同的结果:

for (( i=0; i<=216; i+=24 )); do
    let j=i+24
    let v=(i/24)%2                           #calculate the iteration number
    if [ "$v" -eq 0 ]; then                  #if [ the iteration number is even ]
            printf ""$i" to "$j" is OK\n"
    else
            printf ""$i" to "$j" is not OK\n"
    fi
done

答案 2 :(得分:1)

不确定您是否认为这更优雅,但它更短一点,让您的for循环更清洁:

$ for i in {0..9}; do 
    s="$((i*24)) to $(((i+1)*24)) is"
    ((i%2)) && s+=" not"
    echo "$s OK"
done

或不使用变量s

$ for i in {0..9}; do 
    echo "$((i*24)) to $(((i+1)*24)) is" $(((i%2)) && echo " not") "OK"
done
对于偶数,

((i%2))将评估为0,对于奇数,

((i&1))将评估为0,因此它可用于有条件地添加&#34; not&#34;每隔一次迭代。您还可以使用perl -E 'say $_*24," to ",($_+1)*24," is"," not"x($_%2)," OK" for 0..9' 执行按位AND操作,在这种情况下也会执行相同的操作。

显然,如果你想要优雅,你可能更喜欢使用Perl:

{{1}}

答案 3 :(得分:1)

您可以使用范围进行迭代:

 for i in {0..4}; do
   printf '%s\n%s\n' ""$((i* 48))" to "$((i*48+24))" is OK" ""$((i*48+24))" to "$((i*48+48))" is not OK";
 done

答案 4 :(得分:1)

“优雅”是什么意思?

t=('' 'not ')
for ((i=0, c=0; i<=200; i+=24, c=1-c))
do echo "\"$i\" to \"$((i+24))\" is ${t[c]}OK\n"
done

答案 5 :(得分:0)

使用函数分隔逻辑,例如:

oenum=0
isodd() {
    let oenum++
    (( $oenum % 2 )) && return 0 || return 1
}

do_odd_thing() {
    echo "ODD ($oenum) item: $@"
}

do_even_thing() {
    echo "EVEN($oenum) item: $@"
}

#any loop - e.g. here the find command
while  read -r something
do
    isodd && do_odd_thing "$something" || do_even_thing "$something"
done < <(find /bin -type f -print)

以上产生(至少在我的比赛中):

ODD (1) item: /bin/[
EVEN(2) item: /bin/bash
ODD (3) item: /bin/cat
...
ODD (35) item: /bin/unlink
EVEN(36) item: /bin/wait4path
ODD (37) item: /bin/zsh