我正在尝试搜索所有文件以查找跨越多行的模式,然后返回与该模式匹配的文件名列表。
我正在使用这一行:
find . -name "$file_to_check" 2>/dir1/null | xargs grep "$2" >> $grep_out
这将创建一个文件列表以及在$ grep_out中找到匹配模式的行。这个问题是搜索不跨越多行。我已经读过grep不能跨越多行,所以我想用sed或awk替换grep。
我认为唯一需要改变的是grep。我发现grep无法在多行中搜索模式,所以我希望使用sed或awk。当我从终端使用这些命令时,我获得了与我给出的模式匹配的文件的大打印输出。我想要的只是文件名,而不是模式的上下文。有没有办法检索这个 - 也许有sed打印文件名而不是上下文?或者,当sed找到匹配项时返回true / false,然后我可以保存用于搜索的当前文件名。
答案 0 :(得分:3)
默认情况下,大多数文本处理工具都是面向行的。如果我们选择将记录作为段落读取,则使用空行作为记录分隔符:
awk -v RS= -v pattern="$2" '$0 ~ pattern {print FILENAME; exit}' file
或
find . -options ... -print0 | xargs -0 awk -v RS= -v pattern="$2" '$0 ~ pattern {print FILENAME; exit}'
我假设你的模式不包含连续的换行符(即空行)
检查文件是否包含“word1 [anything] word2 [anything] word3”
暴力:读取整个文件,然后进行正则表达式比较:使用bash
contents=$(< "$file")
if [[ $contents =~ "$word1".*"$word2".*"$word3" ]]; then
echo "match"
else
echo "no match"
fi
<击> 2.与awk一行一行,使用状态机
awk -v w1="$word1" -v w2="$word2" -v w3="$word3" '
$0 ~ w1 {have_w1 = 1}
have_w1 && $0 ~ w2 {have_w2 = 1}
have_w2 && $0 ~ w3 {have_w3 = 1; exit}
END {exit (! have_w3)}
' filename
击> <击> 撞击>
啊,罢工#2:与“word3word2word1”行匹配 - 不强制执行单词的顺序
答案 1 :(得分:1)
我正在尝试搜索所有文件以查找跨越多行的模式,然后返回与该模式匹配的文件名列表。
pattern=$( echo "whatever your search pattern is" | tr '\n' ' ' )
for FILE in *
do
tr '\n' ' ' <"$FILE" | if grep "$pattern" then; echo $FILE; fi
done
只需替换模式和grep-input
中的空格换行符使用'find',您可以这样做:
#!/bin/bash
find . -name "$file_to_check" 2>/dir1/null | while read FILE
do
tr '\n' ' ' <"$FILE" | if grep -q "word1.*word2.*word3" ; then echo "$FILE" ; fi
done >grep_out
至于搜索模式:“。*”表示“任何数量的任何字符”
请记住,grep中的searchpattern总是希望某些字符像“。”一样被转义。变成“\”。并且“^”变为“\ ^”