【问题标题】:Use different variables in one while loop or better use for loop? [duplicate]在一个while循环中使用不同的变量还是更好地使用for循环? [复制]
【发布时间】:2016-05-19 19:57:14
【问题描述】:

请多多包涵,但我昨天才开始有效地使用 bash 编程。

到目前为止,我有一个脚本可以做很多事情。我到了需要遍历变量的地步。我在使用 while 循环之前创建了这些变量。例如,$Time 变量如下所示:

2016-01-29 17:07:00Z
2016-01-29 17:26:20Z
2016-01-29 17:26:20Z
2016-01-29 00:07:00Z

Grabinterval 变量如下:

hour
minute
minute
day

对我来说,第一步是检查不同的变量是否不为空。如果不是,我继续检查$Grabinterval 变量中的每一行,它是dayhourminute。 这也是由一个while循环完成的,效果很好。但没有问题正在上升。现在我想计算在 while 循环之外较早创建的时间与 $Time 变量的第一行中给出的时间之间的时间差。我使用以下代码进行了尝试:

while read -r line; do
if [[ ! -z "$Filelocation" ]]
then 
    if [[ $line = "day" || $line = "days" ]]
    then 
        Interval="Days"
        GrabTimeNew=$(date +'%Y-%m-%d 00:0'$UPOFFSET':00Z')
        default=$(date --date "-1 day" +'%Y-%m-%d 00:0'$UPOFFSET':00Z')
        start=$(date -d"$line$Time" +%s)
        end=$(date -d"$GRABtime" +%s)
        TimeDiff=$(( $start - $end ))
    fi
fi
done <<< $Grabinterval

这只是更大的 while 循环的一部分,寻找 hourminute 的其他两个部分几乎相同。 我在这里使用$line$Time 尝试的方式给了我以下错误消息:

date: invalid date ‘day2016-01-29 17:07:00Z\n2016-01-29 17:26:20Z\n2016-01-29 17:26:20Z\n2016-01-29 00:07:00Z’

所以它遍历所有行,而不仅仅是我希望它通过的 dayline。有没有办法在$Grabinterval变量中使用$Time变量的第一行?

我很想使用 for 循环,但我不知道以后如何在命令块中使用它来在 if 语句的命令块中读取所需的行。

谢谢, 巴勒纳肯

编辑:现在尝试了类似的方法,但也没有用:

while read -r GI TI; do
if [[ ! -z "$Filelocation" ]]
then 
    if [[ $GI = "day" || $GI = "days" ]]
    then 
        Interval="Days"
        GrabTimeNew=$(date +'%Y-%m-%d 00:0'$UPOFFSET':00Z')
        default=$(date --date "-1 day" +'%Y-%m-%d 00:0'$UPOFFSET':00Z')
        start=$(date -d"$TI" +%s)
        end=$(date -d"$GRABtime" +%s)
        TimeDiff=$(( $start - $end ))
    fi
    if [[ $GI = "hours" || $GI = "hour" ]]
    then 
        Interval="Hours"
        GrabTimeNew=$(date +'%Y-%m-%d %H:0'$UPOFFSET':00Z')
        default=$(date --date "-1 hour" +'%Y-%m-%d %H:0'$UPOFFSET':00Z')
        start=$(date -d"$TI" +%s)
        end=$(date -d"$GRABtime" +%s)
        TimeDiff2=$(( $start - $end ))
    fi
    if [[ $GI = "min" || $GI = "minutes" || $GI = "minute" ]]
    then 
        Interval="Minutes"
        GrabTimeNew=$(date +'%Y-%m-%d %H:%M:20Z')
        default=$(date --date "-1 minute" +'%Y-%m-%d %H:%M:00Z')
        start=$(date -d"$TI" +%s)
        end=$(date -d"$GRABtime" +%s)
        TimeDiff3=$(( $start - $end ))
    fi
fi
done < <(paste <(echo "$Grabinterval") <(echo "$Time"))

我没有收到任何错误消息,但在 if 语句/while 循环中没有创建任何变量。

【问题讨论】:

  • “没有创建变量”是什么意思——你怎么知道?你没有打印任何东西
  • 我在控制台中运行代码并查看它们是否已创建,如果是,是否有内容,例如 echo $TimeDiff
  • 那么......那“不起作用”呢?
  • 什么意思?我很困惑......我的脚本不起作用,是的。我不知道为什么,这就是我在这里的原因,希望有人有想法。即使我在任何地方都放置了 echo 来打印想要创建的东西,但我没有从那个 while 循环中得到任何东西。仅使用 done &lt;&lt;&lt; $Grabinterval 可以在 while 循环中提供我想要的所有变量,但仅适用于 $Grabinterval 中的行。所以我对从两个变量读取的更改做错了。但我不知道是什么......
  • 我认为您是在说您在 while 循环中看不到 echo 命令的任何输出。好吧,您确实将 while 循环的内容包含在 if 语句中:$Filelocation 是空的吗?在while 和第一个if 之间,放置echo "$GI - $TI"——你看到那个输出了吗? 那些变量是否保持预期值?

标签: bash variables if-statement for-loop iteration


【解决方案1】:

你可能想尝试这样的事情:

while read -r interval datetime; do
    #...
done < <(paste <(echo "$Grabinterval") <(echo "$Time"))

这将从 Grabinterval 中读取一行,从 Time 中读取相应的行

【讨论】:

  • 看起来不错,但是程序如何知道何时从$Grabinterval 使用$line 以及何时从$Time 使用?目前两者都在同一个while循环中。 if 语句中的$line 必须进入$Grabinterval 变量,if 语句中的$line 需要进入$Time
【解决方案2】:

您需要引用变量以在&lt;&lt;&lt; $var 中保留换行符。

list=$'a\nb\nc'
while read a ; do echo $a ; done <<< $list
while read a ; do echo $a ; done <<< "$list"

【讨论】:

    猜你喜欢
    • 2013-06-28
    • 2011-04-21
    • 1970-01-01
    • 2020-08-14
    • 2011-06-13
    • 1970-01-01
    • 2011-10-06
    • 2020-01-21
    • 1970-01-01
    相关资源
    最近更新 更多