【问题标题】:Bash List files not matching an array of patternsBash List 文件与模式数组不匹配
【发布时间】:2017-07-31 17:04:09
【问题描述】:

我对 bash 没有那么丰富的经验,我有一个问题。

我正在尝试选择一些与特定数组 o 模式不匹配的文件(在此示例中假设为 ls)。

我需要在两组中选择名为 Test,Test1,Test2,Test3,Test4,Test5,Test6,Test7,Test8,Test9,Test10 的文件。

第一组是 Test5,Test6,Test7,Test8,Test9,Test10,我可以使用:

ls -l T*@(5|6|7|8|9|10) or ls -l T*{5,6,7,8,9,10}

由于 Test & Test1 文件,第二组是棘手的(对我来说)。我正在尝试反转先前的选择/列表..或以某种方式选择其余的。 我尝试了几件事但没有运气:

ls -l T*[!5678910]
ls -l T*[!@(5|6|7|8|9|10)]
ls -l T*[!5][!6][!7][!8][!9][!10]
ls -l T*@(1|2|3|4|)

p.s:实际文件名的数字后面有多余的字符。

【问题讨论】:

  • 一个建议,而不是p.s: the actual filenames have extra characters after the number,请添加完全代表手头问题的示例......此外,所有文件都有Test共同点,而不仅仅是开始T所以甚至@987654326 @ 会起作用...这样的事情会导致特定于所示示例的解决方案..很容易错过最后一句话
  • 事实证明这无关紧要,该解决方案适用于我的实际文件(不是这里的测试示例)。谢谢。

标签: bash pattern-matching


【解决方案1】:

你可以像这样反转一个模式:

# enable extended glob, if disabled, it will not function
shopt -s extglob

# create our files
touch {Test,Test1,Test2,Test3,Test4,Test5,Test6,Test7,Test8,Test9,Test10}

# list files with matching pattern
ls -1 T*@(5|6|7|8|9|10)
Test10
Test5
Test6
Test7
Test8
Test9


# list files with NOT matching pattern
ls -1 T!(*@(5|6|7|8|9|10))
Test
Test1
Test2
Test3
Test4

【讨论】:

  • 你试过了吗?在 bash 我得到“bash: !: event not found”
  • 感谢您的快速回复! ls -1 T!(*@(5|6|7|8|9|10)) 如我所愿!我也会尝试其他建议。
  • @marek.jancuska:当然,我在 bash 中对此进行了测试,并在此处复制/粘贴了结果。您需要使用shopt -s extglob为此启用extglob
  • @anubhava - 我明白了,将它添加到你的答案中,我认为它会更有用(人们可能禁用了 extglob)
【解决方案2】:

您可以在列表中使用空字符串作为选项:

ls -l Test*{,1,2,3,4}

[编辑] 但总的来说,我看不到单独在 bash 中进行反向匹配的方法。我现在还看到数字后面可能还有其他字符(我想是非数字的,否则您将无法区分)。我会使用 'grep' ,可能会使用 '-v' 标志进行否定。

ls -1 |  grep -v "Test\(\(5\)\|\(6\)\|\(7\)\|\(8\)\\|\(9\)\|\(10\)\)"

【讨论】:

  • OP 询问:I am trying to invert the previous selection/listing
  • 第一个为我返回所有内容,但第二个工作正常!
  • 好吧,他似乎不需要一般情况下的否定,但当然,一般情况下更好
【解决方案3】:

我不确定为什么它不适用于 *,但它适用于更具体的模式:

ls -l Test@(1|2|3|4|)
ls -l Test?([1-4])
ls -l T+([^0-9])?([1-4])

【讨论】:

  • 据我了解,问题从 T*@(1|2|3|4|) 开始,它返回全部,而 Test@(1|2|3|4|) 返回正确的 (以及测试?([1-4]))。我从来没有想过会如此不同。
【解决方案4】:

如果ls不是你唯一可以接受的命令,你也可以使用findregex来达到你的目的:

  • 创建所有测试文件:

    touch Test{,1,2,3,4,5,6,7,8,9,10}

  • 使用regex 查找您的第一组文件:

    find -type f -regex "\./Test\([5-9]\|10\)"

  • 反向很简单,只需在选项-regex之前添加一个!

    find -type f ! -regex "\./Test\([5-9]\|10\)"

它适用于 Linux Bash。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 2012-01-21
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多