我见过这个问题: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
答案 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