【问题标题】:run two for loops in one line when first glob fails当第一个 glob 失败时,在一行中运行两个 for 循环
【发布时间】:2019-07-11 11:18:49
【问题描述】:

我正在尝试运行这个:

for file in a?; do echo $file; done; for file in b?; do echo $file; done

如果有匹配 a?b? 的文件,两个循环都会运行(预期)

但如果没有a? 文件,我会收到此错误

zsh: no matches found: a?

第二个循环永远不会运行。

我怎样才能始终运行两个循环?

我意识到我可以将a?(N) 放入(N) glob 参数以跳过错误,但如果没有找到匹配项,我仍然希望第一个循环的no matches found 输出。

【问题讨论】:

    标签: shell terminal zsh glob


    【解决方案1】:

    你可以在zsh

    unsetopt nomatch    
    for f in a?; do [[ -e "$f" ]] && echo "$f" || echo "no matches found"; done
    
    setopt nomatch
    for f in b?; do echo "$f"; done
    

    zsh nomatch option

    【讨论】:

      【解决方案2】:

      由于您只是回显文件名,因此无需循环。

      a_files=( a?(N) )
      if (( ${#a_files} > 0 ))
      then
        # We have at least one entry starting with 'a'
        echo $a_files
        echo b?(N)
      fi
      

      假设你确实需要一个嵌套循环,因为你想用 a 和 b 文件处理一些东西,你可以做 a

      a_files=( a?(N) )
      if (( ${#a_files} > 0 ))
      then
        # We have at least one entry starting with 'a'
        for a_file in $a_files
        do
            echo $a_file
            for b_file in b?(N)
            do
               do_something_with $a_file $b_file
            done
        done
      fi
      

      更新:

      依次运行两个循环,但保证每个循环至少运行一次:

      a_loop_entered=0
      for file in a?(N) .
      do
        if [[ $file != . || $a_loop_entered==0 ]]
          a_loop_entered=1
          # Now do your loop body. 
        fi
      done
      

      【讨论】:

      • 显然我的问题只是一个小例子,我想要运行的真正命令不仅仅是回显文件名。而且我认为您误解了我不想运行嵌套循环的问题。
      • 但是您有两组文件 - 以 a 开头和以 b 开头 - 您想为这些文件的每个组合执行命令吗?这正是嵌套循环所做的。
      • 我不想处理每个组合的命令。阅读问题,我的示例代码 sn-p 的逻辑是有意的。我想依次运行两个不同的循环。
      • @theonlygusti :我更新了我的答案以反映这一点。
      猜你喜欢
      • 1970-01-01
      • 2016-01-15
      • 1970-01-01
      • 2019-01-05
      • 2015-01-20
      • 2020-02-19
      • 2020-12-27
      • 2023-03-18
      • 1970-01-01
      相关资源
      最近更新 更多