You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash 4.1.2(2):如何在for循环中实现正则反向匹配?

解决Bash遍历不含指定字符串目录的问题

你的问题出在Bash的路径扩展(glob)不支持PCRE风格的正则表达式——你写的^((?!unicredit*).)*$是正则语法,但Bash默认的通配符是glob模式,不识别这种负向前瞻语法,所以会报语法错误。

下面给你几种可行的修改方案:

方案1:使用Bash扩展通配符(extglob)

这是最原生的Bash解决方案,开启extglob后可以直接用排除式匹配:

  1. 先开启扩展通配符(如果没开的话):
shopt -s extglob
  1. 执行遍历命令:
for i in /tmp/scripts/bash/test/!(*unicredit*); do echo FOUND $i; done

这里的!(*unicredit*)是extglob的语法,表示匹配所有不包含"unicredit"的条目,完全符合你的需求,会输出:

FOUND /tmp/scripts/bash/test/par_q
FOUND /tmp/scripts/bash/test/swx_i
FOUND /tmp/scripts/bash/test/swx_r

方案2:用find命令过滤(更安全,适合复杂场景)

如果不想依赖extglob,或者需要处理含特殊字符的文件名,用find更可靠:

find /tmp/scripts/bash/test/ -maxdepth 1 -type d ! -name "*unicredit*" ! -path "/tmp/scripts/bash/test/" | while read -r dir; do echo FOUND "$dir"; done

参数解释:

  • -maxdepth 1:只遍历目标目录的直接子目录,不深入递归
  • -type d:只筛选目录(排除文件)
  • ! -name "*unicredit*":排除名字包含"unicredit"的目录
  • ! -path ...:排除目标目录本身(避免输出/tmp/scripts/bash/test/)

方案3:结合ls和grep(简单但需注意文件名空格)

如果场景简单,也可以用管道配合grep过滤:

ls -d /tmp/scripts/bash/test/* | grep -v "unicredit" | while read -r dir; do echo FOUND "$dir"; done

-v参数表示反向匹配,即排除包含"unicredit"的行。不过这种方法如果文件名包含空格或特殊字符可能出问题,优先推荐前两种方案。

为什么原命令报错?

Bash的for循环里的路径是用glob模式匹配的,而不是正则表达式。你写的^、(?!...)这些都是PCRE正则的语法,Bash glob完全不识别,会把括号当成命令语法的一部分,所以触发syntax error near unexpected token '('的错误。

内容的提问来源于stack exchange,提问作者kamokoba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 10:57:35