如何与正则表达式进行反向匹配/黑名单?

时间:2013-12-02 17:56:25

标签: regex shell unix

我见过这个问题:Regular expression to match a line that doesn't contain a word?

但我无法让它发挥作用。我有一个shell脚本,我正在使用

string1.*string2.*string3

按顺序搜索文件中的3个单词。但我想改变它,以便如果badword5在该文件中的那些单词之间的任何位置,则没有与grep的正则表达式匹配。

所以这应该匹配:

./testing/test.txt:   let prep = "select string1, dog from cat",
          " where apple = 1",
          " and string2 = 2",
          " and grass = 8",
          " and string3 = ?"

但这不应该:

   ./testing/test.txt:   let prep = "select string1, dog from cat",
          " where apple = 1",
          " and string2 = 2",
          " and grass = 8",
          " and badword5 = 4", 
          " and string3 = ?"

我没试成功:

string1((?!badword5)|.)*string2((?!badword5)|.)*string3

整个脚本:

find . -name "$file_to_check" 2>/null | while read $FILE
do
   tr '\n' ' ' <"$FILE" | if grep -q "string1.*string2.*string3"; then echo "$FILE" ; fi
done >> $grep_out

2 个答案:

答案 0 :(得分:1)

“按顺序在文件中搜索3个单词。但是我想更改它,以便如果badword5位于该文件中的那些单词之间的任何位置,则grep没有正则表达式匹配。“

确实,搜索模式延伸了多行 让我们暂时放弃grep并尝试不同的东西:

#!/bin/bash

find . -name "$file_to_check" 2>/dev/null | while read FILE
do
    SCORE=0
    tr ' ' '\n' <"$FILE" | while read WORD
    do
        case $WORD in
        "word1"    ) [ $SCORE = 0 ] && SCORE=1               ;;
        "word2"    ) [ $SCORE = 1 ] && SCORE=2               ;;
        "word3"    ) [ $SCORE = 2 ] && echo "$FILE" && break ;;
        "badword5" ) SCORE=0                                 ;;
        esac
    done        
done >grep_out

案例行做了以下事情:

"    word1"      )    [ $SCORE     =       0 ] &&      SCORE  =       1  ;;
when word1 is found: and SCORE is equal to 0 then make SCORE equal to 1
when word2 is found: and SCORE is equal to 1 then make SCORE equal to 2
when word3 is found: and SCORE is equal to 2 then print filename and break out of the inner loop.

答案 1 :(得分:0)

您可以使用grep -v跳过badword5的行:

tr '\n' ' ' < "$FILE" | grep -v 'badword5' | if grep -q "string1.*string2.*string3"; then echo "$FILE" ; fi