Grep,找到具有精确匹配模式数的行

时间:2018-09-28 15:20:17

标签: linux unix grep

我想在文本文件中查找并列出仅包含两个等于或大于四个字符的单词的行。

我可以找到四个字符或更多的单词:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	  xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
	<!-- Font Awesome -->
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	<!-- Bootstrap core CSS -->
	<link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/4.1.3/css/bootstrap.min.css}"/>
	<link rel="stylesheet" type="text/css" th:href="@{/static/css/main.css}"/>
</head>

但是如何限制输出以仅显示带有两个这样的单词的行?

有任何提示(不一定是答案)吗?

谢谢

更新: 谢谢。遵循您的建议后,我现在使用:

grep '[A-Za-z][A-Za-z][A-Za-z][A-Za-z][A-Za-z]*' file.txt

列出所有带有突出显示的单词且长度超过4个字母的行。现在,我只需要过滤它,以仅显示出现此类单词(长4个以上的字母)两次的行。有提示吗?

3 个答案:

答案 0 :(得分:1)

要查找PATTERN的两个实例,请使用:

PATTERN.*PATTERN

如果您使用grep -E,则可以使用花括号来避免重复:

grep -E '(.*PATTERN){2,}'

(您也可以应用相同的技巧来避免在模式中重复[A-Za-z]。)

您可以使用\<\>来匹配单词的开头和结尾,以确保不会将8个字母的单词检测为两个4个字母的单词。

答案 1 :(得分:1)

只需使用awk,您就不必想出一些复杂的正则表达式来一次完成所有操作。使用GNU awk作为单词边界,并假设您的“单词”仅包含字母字符,如您发布的脚本中一样:

awk 'gsub(/\<[[:alpha:]]{4,}\>/,"&") == 2'

当然,以上内容未经测试,因为您没有提供样本输入/输出供我们测试。

编辑: 这是the text you referenced中第216页在您的评论中对第100页的练习7.5给出的解决方案,您的问题基于此:

egrep '(\<[A-Za-z]{4,}\>).*\<\1\>' file

我们首先进行清理,以删除不推荐使用的egrep并将字符列表替换为可移植字符类:

grep -E '(\<[[:alpha:]]{4,}\>).*\<\1\>' file

现在您拥有的是一个脚本,而不是查找问题中包含only two words that are four characters or more的行,而是查找包含相同 4个或更多字符的行至少发生两次 ,这是一个非常不同且更简单的问题。

答案 2 :(得分:0)

第一:我建议使用\ w(字母)作为字母,这样更干净。
第二:要将模式分组为单个令牌,请使用(),以查找正则表达式令牌的多个副本。 (请参阅备忘单)
第三:在这种情况下,您的定界符为空格,因此我将使用{},因为我假设您可能想捕获选项卡之类的东西。但这是您自己决定的。

旁注:我建议避免使用\s,除非您使用强定界符(例如*会贪婪地匹配字符串的末尾)。

备忘单:https://www.rexegg.com/regex-quickstart.html