【问题标题】:Match group of files, excluding one specific file, in Bash在 Bash 中匹配一组文件,不包括一个特定文件
【发布时间】:2020-01-15 13:16:54
【问题描述】:

我有一堆具有以下名称的文件:text.shtexttext.1text.2 等。如何在我的 bash 脚本中引用除 text.sh 之外的所有这些文件?我尝试使用text*,但它也匹配text.sh

【问题讨论】:

    标签: regex bash shell glob


    【解决方案1】:

    启用扩展通配符并使用排除列表。

    shopt -s extglob
    echo text!(.sh)
    

    【讨论】:

    • 感谢您的反馈。这几乎奏效了。但是这不包括文件test
    • 此答案不包括 test,因为 . 不在排除“分组”范围内。应该是text!(.sh),不是吗?
    • @Mark 我进行了更改,但现在它还将包括text1 而没有.。可以吗?
    • @Barmar:没问题。
    【解决方案2】:

    @Barmar 的答案与我的基本相同,但在 shell 脚本中迭代 ls 的输出通常是不好的做法。迭代有很多不同的选项,一个是 for 循环:

    shopt -s extglob
    for file in text!(.sh) ; do ... ; done
    

    另请参阅:https://unix.stackexchange.com/questions/164025/exclude-one-pattern-from-glob-match

    【讨论】:

    • 我并不是说他应该遍历ls 输出,这只是一种查看匹配内容的方法。我把它改成了echo
    【解决方案3】:

    试试这个命令,会出现与text.sh不匹配的文件:

     ls -l !(text.sh) 
    

    这将是你的输出:

    -rw-rw-r-- 1 myuser mygroup 0 sep 13 10:44 text
    -rw-rw-r-- 1 myuser mygroup 0 sep 13 10:45 text.1
    -rw-rw-r-- 1 myuser mygroup 0 sep 13 10:45 text.2
    

    顺便说一下,另一种解决方案,更复杂:

      ls -l !(text.sh|!(text?(.)*));
    

    【讨论】:

      【解决方案4】:

      我会这样做:

      for file in text*; do
          [[ $file == 'test.sh' ]] && continue
          # Processing
      done
      

      这避免了扩展 glob 遇到的所有边缘情况。如果您希望它可移植到任何 POSIX shell,您可以改用 [ ]

      for file in text*; do
          [ "$file" = 'test.sh' ] && continue
          # Processing
      done
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-03
        • 1970-01-01
        • 2013-03-24
        • 2012-04-21
        相关资源
        最近更新 更多