【问题标题】:Bash - Multiple conditions in a for loopBash - for 循环中的多个条件
【发布时间】:2012-08-04 17:12:01
【问题描述】:

我正在尝试使用多个条件进行 for 循环,但我没有在网络上找到有关如何执行此操作的任何信息

对于这些愚蠢的问题,我很抱歉,但我刚开始在 linux 中编程

我在这里做错了什么?

    #!/bin/bash

j=0

for line in `cat .temp_` || j in `seq 0 19`
do
    ...

done

错误提示语法错误,我无法使用 ||

非常感谢

【问题讨论】:

    标签: linux bash shell loops


    【解决方案1】:

    一旦我需要处理目录中的所有文件,但只处理到第 n 个文件或处理完所有文件:

    count=1
    nth=10
    for f in folder/*; do
      ((count++))
      # process $f
      if [[ $count -gt $nth ]] 
      then
        break
      fi
    done
    

    【讨论】:

      【解决方案2】:

      一个简单的嵌套for循环?

      for line in `cat file`; do for j in {0..19}; do
           your_commands
      done; done
      

      如果我理解正确的话(你想在每行运行一个命令 20 次)。

      【讨论】:

      • 不,不是嵌套的,我只是想在 20 次后打破一段时间
      • 哦,现在明白其他答案了:)
      【解决方案3】:

      您正试图将两种不同样式的for-loops 合并为一个。相反,如果j 的值变得太大,就中断:

      j=0
      while read -r line; do
          [[ j >= 20 ]] && break
          ...
      done < ._temp
      

      (顺便说一句,这是在 bash 中迭代文件的首选方法。如果文件太大,使用 for-loop 会遇到问题,因为您实际上是使用整个内容构建命令行文件。)

      [更新:以下内容基于我对循环目的的猜想。真实情况见Calculate Word occurrences from file in bash。]

      实际上,您可以省去循环。您正在从 .temp_ 中查找最多 20 行尚未出现在名称在字典中的文件中的行,对吧?

      sort -u .temp_ | grep -f $dictionary -Fx -v -m 20 >> $dictionary
      

      这将只调用一次grep,而不是.temp_ 中的每行一次。

      【讨论】:

      • 最后一个解决方案(使用 sort -u 和 head)不正确。如果您在 .temp_ 中有未排序的行,它可能会产生错误的结果
      • 对。我意识到输出中可能存在重复,但没有考虑消除它们的最佳方法。我会更新的。
      • 这样更好,但现在你失去了.temp_ 中的行顺序。也许您可以编写这两种变体并解释它们之间的区别? (无论如何+1)
      • 鉴于 Epi 的最新问题 (stackoverflow.com/questions/11850823/…),我将停止对循环进行二次猜测 :)
      • @chepner:哇,我还没有看到这个问题。看起来很有趣:)
      【解决方案4】:
      for line in `cat .temp_`
      do
          if ! grep -Fxq $line $dictionary && [ $j -lt 20 ]
          then
              echo $line >> $dictionary
              j=$((j+1))
          fi
          [ $j -gt 20 ] && break
      done
      

      您无法在 shell 的 for 循环中检查条件。你必须在一个额外的声明中做到这一点。 在这种情况下:

      [ $j -gt 20 ] && break
      

      另一种解决方案,没有break

      while read line && [ $j -lt 20 ]
      do
          if ! grep -Fxq $line $dictionary && [ $j -lt 20 ]
          then
              echo $line >> $dictionary
              j=$((j+1))
          fi
      done < .temp_
      

      【讨论】:

      • 好的,谢谢,但那不是 O(n^2),就像一个在另一个里面?如果这是我要问的,那么语法对我来说看起来很奇怪:O
      • 对不起,我第一次没有抓住重点;但现在我做到了;我已经重写了脚本。
      • kk,非常感谢 :) 没有休息的更优雅的方式吗?
      • 为什么不呢?添加了另一个解决方案:)
      猜你喜欢
      • 2020-04-10
      • 2020-08-21
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 2013-05-27
      • 2013-01-27
      • 2011-09-02
      相关资源
      最近更新 更多