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

Bash脚本正则匹配:特定字符串附近不含指定词的行

解决包含特定字符串且前后指定范围无禁止词的匹配问题

看起来你想要筛选出包含目标字符串(比如qwe),并且该字符串前后0-3个字符范围内不出现指定禁止词(比如dfg或qq)的内容。我先帮你分析下当前脚本的问题,再给出正确的实现。

现有脚本的问题

  1. 循环方式错误:用for x in $(cat ./test2.txt)会把文件内容按空格拆分成单个单词处理,但你的输入是一整行文本,应该用while read来逐行读取,这样才能处理完整的行。
  2. 正则逻辑反向:你当前的正则^.*"$1".\{0,3\}(dfg|qq).*$是在匹配包含目标字符串且后面0-3字符内有禁止词的内容,但你的需求是要排除这种情况,保留符合条件的行。
  3. 范围不完整:只考虑了目标字符串后面的字符范围,没覆盖前面的部分。

正确的实现方案

下面提供两种方式,一种是修正后的Bash脚本,另一种是更简洁的grep命令实现:

方式1:修正后的Bash脚本

这个脚本会逐行读取文件内容,检查每行是否包含目标字符串,且目标字符串前后0-3个字符范围内没有禁止词:

#!/bin/bash
# 开启扩展正则支持
shopt -s extglob

# 检查参数是否传入
if [ $# -eq 0 ]; then
    echo "请传入目标字符串,例如:./test.sh qwe"
    exit 1
fi

target="$1"
forbidden_words="dfg|qq"

# 逐行处理文件内容
while read -r line; do
    # 先检查行是否包含目标字符串
    if [[ "$line" == *"$target"* ]]; then
        # 检查是否存在目标字符串前后0-3字符内有禁止词的情况,不存在则输出
        if ! [[ "$line" =~ .{0,3}($forbidden_words).{0,3}$target|$target.{0,3}($forbidden_words).{0,3} ]]; then
            echo "$line"
        fi
    fi
done < ./test2.txt

方式2:用grep命令直接实现

如果不需要复杂的脚本逻辑,用grep结合Perl正则(-P参数)可以更简洁地完成需求:

grep -P "(?<!.{0,3}(dfg|qq))qwe(?!.{0,3}(dfg|qq))" test2.txt

解释下这个正则:

  • (?<!.{0,3}(dfg|qq)):否定后顾,确保qwe前面0-3个字符内没有dfg或qq
  • qwe:匹配目标字符串
  • (?!.{0,3}(dfg|qq)):否定前瞻,确保qwe后面0-3个字符内没有dfg或qq

测试效果

对于你的输入内容:qweisdfg qwe is dfg dfg qwe qwe is qq

  • 第一个qweisdfg中,qwe后面第3个字符是d(属于dfg的一部分),所以会被排除
  • 后面的qwe is dfg dfg qwe qwe is qq中,每个qwe前后0-3字符内都没有dfg或qq,所以会被保留,完全符合你的期望输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:02:34