我有一组文件需要循环查找并找到其他两个特定字符串之间没有特定字符串的所有文件。我怎样才能做到这一点?
我尝试了这个,但它没有用:
grep -lri "\(stringA\).*\(?<!stringB\).*\(stringC\)" ./*.sql
编辑: 该文件可以具有以下结构:
StringA
StringB
StringA
StringC
所有我想要知道是否存在字符串A和stringC之间没有stringC的任何事件。
答案 0 :(得分:2)
简短的回答是:
grep "abc[^(?:def)]*ghi" ./testregex
这是基于如下的testregex文件:
abcghiabc
abcdefghi
abcghi
输出将是:
$ grep "abc[^(?:def)]*ghi" ./testregex
abcghiabc
abcghi
映射到您的用例,我打赌这大致翻译为:
grep -lri "stringA[^(?:stringB)]*stringC" ./*.sql
请注意,我删除了每个字符串之间的“。*”,因为它会匹配您尝试排除的字符串。
更新:原来的问题现在调出换行符,所以使用grep的-z标志:
-z
在行尾压缩换行符,将其替换为空字符。也就是说,grep知道行尾的位置,但将输入视为一个大行。
因此:
grep -lriz "stringA[^(?:stringB)]*stringC" ./*.sql
当我第一次不得不自己使用这种方法时,我写下了以下解释......
具体来说:我想匹配“任何角色,任何次数, 非贪婪(因此推迟后续的显式模式),而不是 匹配序列/&gt;“。
最后一部分是我要写的内容:“不符合序列 /&gt;“。这是我第一次使用字符序列组合 用“任何字符”逻辑。
我的目标字符串:
<img class="photo" src="http://d3gqasl9vmjfd8.cloudfront.net/49c7a10a-4a45-4530-9564-d058f70b9e5e.png" alt="Iron or Gold" />
我的第一次尝试:
<img.*?class="photo".*?src=".*?".*?/>
这适用于在线正则表达式测试人员,但由于某种原因失败了 我的实际Java代码。通过反复试验,我发现了更换 每一个“。?”用“[^&lt;&gt;] ?”那是成功的。也就是说,而不是 “任何角色的非贪婪匹配”,我可以使用“非贪婪 除了&之外的任何字符的匹配或&gt;“。
但是,我不想使用它,因为我看过alt文本 包括这些字符。在我的特殊情况下,我想使用 字符序列“/&gt;”作为排除序列 - 一旦那样 遇到序列,停止“任何字符”匹配。
这让我接受了教训:
第1部分:使用(?:regex)可以实现字符序列。那是, 使用()括号作为字符序列的正常,但前缀 使用“?:”以防止序列匹配为a 目标组。 Ergo,“(?:/&gt;)”将匹配“/&gt;”,而“(?:/&gt;)*”将 匹配“/&gt; /&gt; /&gt; /&gt;”。
第2部分:这些字符序列的使用方式与之相同 单个字符。也就是说,“[^(?:/&gt;)] *?”将匹配任何角色 除了序列“/&gt;”,任何次数,非贪婪。
这就是它。用于搜索的关键字是“非捕获” 群体“和”负向前瞻|看后面“,以及后者的特征 比我走得更远,我还有更多的旗帜 还没有意识到。但最初的理解给了我一个工具 我当前的任务需要,这是我想知道的一个功能 关于一段时间 - 因此,我想我会分享基本的介绍 如果你们中的任何一个人都好奇想把它藏在你的工具箱里。
答案 1 :(得分:2)
您可以使用-L
的{{1}}选项打印所有不匹配的文件,并查找特定的字符串组合:
grep
答案 2 :(得分:0)
在玩弄DreadPirateShawn提供的声明之后:
stringA[^(?:stringB)]*stringC
我发现它不是一个真正有效的正则表达式。此语句排除给定集合中的每个字符而不是完整字符串。所以我继续挖掘。
经过一些谷歌搜索和测试模式,我想出了以下声明,似乎符合我的需求:
stringA\s*\t*(?:(?!stringB).)*\s*\t*stringC
此模式匹配2个指定字符串之间的除提供的字符串之外的任何文本。它还考虑了空格字符。
还有更多的测试要做,但似乎这种模式完全符合我的要求
更新:这是一个似乎对我有用的声明的最终版本:
grep -lriz "(set feedback on){0,}[ \t]*(?:(?!set feedback off).)*[ \t]*select sysdate from dual" ./*.sql