如何使用grep在平面文件数据库中的字段中查找特定单词?

时间:2009-09-20 00:33:18

标签: grep

我需要这个grep电话:

grep "field3=highland" data_file

用“field3 = highland”以及“field3 = chicago highland”返回两个结果。 如何重新设计grep调用以解决这两种情况?

5 个答案:

答案 0 :(得分:2)

你可以使用*通配符

grep "field3=.*highland" data_file

答案 1 :(得分:2)

专家组,

我的建议是花更多精力撰写你的问题。

你在主题中提到“grep工具(Linux)”和“SQL LIKE运算符”...然后包括一个坦率的难以理解的问题,似乎是关于匹配输入样本行的两个不同变体。 / p>

你得到的答案只是猜测你的实际问题可能是什么。

我认为这个问题是:

“我的数据包含以下行:field3=highlandfield3=other stuff highland,我希望匹配所有这些行(过滤掉所有其他行)。”

最简单的正则表达式可能是:

grep "field3=.*highland

...但是这会匹配像“field3 = highlands”和“field3 = thighland”和“myfield3 = ...”之类的东西,等等。它也无法匹配“field3 = ...”(与场指示符和等号之间的空格。)

“field3”应该在行的开头吗?高地应该固定在线路的尽头吗?如果“高地”不是更长的“单词”中的子字符串(即如果“h”之前和“d”之后的字符是非字母的),那么它应该匹配吗?

关于您的预期输入和期望结果有很多问题......这将对将匹配与否匹配的正则表达式产生相当大的影响。

对SQL LIKE表达式的引用及其%标记几乎没用。在大多数情况下,SQL LIKE表达式中的%标记等同于“。*”正则表达式。如果你有一个可用的SQL片段(在相同的输入范围内)并且你试图找到一个功能相同的正则表达式......那么你应该花时间粘贴在工作的SQL表达式中。

此问题中没有特别针对grep(Linux或其他)的内容。它会被更好地标记为关于正则表达式的问题。

通常,有三到四个常见的抽象用于匹配模式的文本:正则表达式(有许多变体),“glob”和“wildmat”模式(shell和MS-DOS类似)和SQL LIKE表达式。

这些正则表达式是程序员最常用的......到目前为止,它们是最复杂的。它们的范围从最古老的最简单的变体(包括在ed行编辑器中,grep被引用)到更强大的“扩展”版本(以egrep为代表)或grep -E)以及精心制作的“Perl兼容正则表达式”(现在被其他编程语言广泛用作PCRE库)。

全球模式简单得多。他们支持“贝壳外卡”......最初只是?和*(任何单个字符,或任何数字的任何字符)。现代shell和其他工具支持的后期增强功能包括对字符类的支持(例如任何数字的[0-9]和任何字母的[a-zA-Z],等等)。其中一些还支持否定的字符类。

因为glob模式使用与正则表达式语法类似的特殊字符(?和*),尽管出于不同的目的......并且因为它们使用几乎相同的语法来描述字符类及其补充,所以glob模式经常被误认为是常用表达。当我教授系统管理课程时,我通常必须提出这一点,以便学生“忘掉”那些常见的术语的邋。。

旧的MS-DOS“wildmat”或“通配符匹配”可以被认为是原始glob模式的变体。它只支持?和*元字符...与UNIX shell globbing大致相同的语义。但是,我建议不要这样想他们。 MS-DOS命令行如何处理包含这些模式的参数的基本语义是完全不同的,将它们视为“globs”是一个陷阱。 (像COPY *.TXT *.BAK这样的命令在MS-DOS下是完全合理的,而像cp *.txt *.bak这样的UNIX命令在几乎任何合理的情况下都是错误的。)

显然,正如我上面所描述的,SQL LIKE表达式与UNIX glob非常相似。在大多数基本的SQL LIKE实现%(类似于*)和_(类似于?)中只有两个“特殊”或“元”字符。

请注意这里的狡猾的话。我不会声称%一个glob *相同,而且_ 一个glob相同?字符。可能存在一些极端情况(关于这些情况如何在字符串的开头或结尾处批处理,或者与空格相邻等)。 SQL的不同实现之间可能存在差异,甚至可能存在一些虚拟版本的UNIX / Linux fnmatch (globbing)库,如果您尝试依赖此类声明,这些库会产生影响。

答案 2 :(得分:1)

$ grep 'f=h\|f=c h' << eof
> f=c h
> f=h
> not
> going f= to
> match
> eof
f=c h
f=h
$ 

或者,如果想法是c可以是任何东西,可能是这样的:

$ grep 'f=.*h' 

答案 3 :(得分:1)

如果您希望获得所有包含'field3 ='的行,后跟任何字符后跟'highland',您需要:

grep 'field3=.*highland' data_file

'.'表示任何字符,'*'表示最后一个模式出现零次或多次。所以'.*'实际上是任何字符串,包括空字符串。

答案 4 :(得分:0)

如果您的意思是将该行的第三个字段与您的字符串匹配(而不是匹配文字“field3=highland”)grep不适合您。在这种情况下,请考虑awk

awk '$3=="highland" { print $0 }' <input file>

完全匹配或

awk '$3~".*highland.*" { print $0 }' <input file>

与正则表达式匹配。

请注意,awk假设一个空格作为字段分隔符,但您可以使用“-F <field separator>”在命令行上更改它,以便

awk -F : '$1~".*oo.*" {print $0}' /etc/passwd

从密码文件中获取根线。