您好我的第一篇文章是我认为简单的...
我无法找到类似问题/解决方案的示例。
我有数千个文本文件,其中包含数千行内容
<word><space><word><space><number>
示例:
example for 1 useful when 1 for. However 1 ,boy wonder 1 ,hary-horse wondered 2
在上面的示例中,我想排除第3行,因为它包含内部标点符号
我正在尝试使用GNU grep 2.25,但没有运气
我最初的尝试是(但这不允许模式内部的“ - ”):
grep -v [:alnum:]*[:punct:]*[:alnum:]* filename
所以试过这个
grep -v [:alnum:]*[:space:]*[!]*["]*[#]*[$]*[%]*[&]*[']*[(]*[)]*[*]*[+]*[,]*[.]*[/]*[:]*[;]*[<]*[=]*[>]*[?]*[@]*[[]*[\]*[]]*[^]*[_]*[`]*[{]*[|]*[}]*[~]*[.]*[:space:]*[:alnum:]* filename
但是我需要考虑空格和 - 因为这些是字符串内部可接受的。
我一直在尝试使用:punct“set但是现在看到它包含 - 显然不会起作用
我目前在TSQL中有一个存储过程来处理这些,但是如果可能的话,我希望在加载之前进行预处理,因为例程每个文件需要几秒钟。
有人能够取得类似的成就吗?
答案 0 :(得分:1)
你的正则表达式包含一长串有序的可选元素,但这意味着如果出现故障,它将会失败。例如,
[!]*[?]*
将捕获!?
但不捕获?!
(当然,包含单个字符的字符类只相当于该单个字符,因此您可以说!*?*
)。
您可以改为使用包含要捕获的所有符号的单个字符类。一旦你看到一个字母数字字符旁边的一个,你就完成了,所以你不需要正则表达式来匹配整个输入行。
grep -v '[[:alnum:]][][!"#$%&'"'"'()*+,./:;<=>?@\^_`{|}~]' filename
还要注意表达式如何在单引号中,以便shell不会干扰这里的许多元字符。为了使单引号字符串包含文字单引号,我暂时分成双引号字符串;请参阅here获取解释(我称之为#34;跷跷板引用&#34;)。
在字符类中,如果类需要包含]
,则它必须位于枚举列表的开头;为了对称性和成语,我还在它旁边移动了[
。
此外,正如Jonathan Leffler所指出的,POSIX字符类名称需要在字符类中;因此,要匹配属于[:alnum:]
命名集的一个字符,请说[[:alnum:]]
。 (这意味着您可以组合集合,因此[-[:alnum:].]
涵盖字母数字加上短划线和句号。)
如果您需要将其限制为仅匹配第一个字段,请将[[:alnum:]]
更改为^[[:alnum:]]\+
。
没有意识到a*b*c*
匹配任何是一个常见的新手错误。您希望避免编写一个表达式,其中所有元素都是可选的,因为它将匹配每个可能的字符串。关注你想要匹配的内容(在你的情况下,标点字符的长列表),然后如果你真的需要,可以在它周围添加可选的上下文位;但是你需要的越少,它运行得越快,看它的作用就越容易。作为一个快速的经验法则,a*bc*
实际上恰好等同于b
- 可能也没有指定前导或尾随可选表达式,因为它们不会影响要匹配的内容。 / p>
答案 1 :(得分:0)
从表面上看,您正在寻找空格字空间编号&#39;架构,假设&#39;字&#39;是一个字母数字,可选地后跟零或一次出现的零个或多个字母数字或标点字符,并以字母数字&#39;和&#39;空格&#39;结尾。是一个或多个空格&#39;和&#39;数字&#39;是一个或多个数字&#39;。
就grep -E
(又名egrep
)而言:
grep -E '[[:alnum:]]([[:alnum:][:punct:]]*[[:alnum:]])?[[:space:]]+[[:alnum:]]([[:alnum:][:punct:]]*[[:alnum:]])?[[:space:]]+[[:digit:]]+'
包含:
[[:alnum:]]([[:alnum:][:punct:]]*[[:alnum:]])?
检测到包含字母数字的任何标点符号的单词,并且:
[[:space:]]+
[[:digit:]]+
寻找一个或多个空格或数字。
使用温和扩展的数据文件,这会产生:
$ cat data
example for 1
useful when 1
for. However 1
,boy wonder 1
,hary-horse wondered 2
O'Reilly Books 23
Coelecanths, Dodos Etc 19
$ grep -E '[[:alnum:]]([[:alnum:][:punct:]]*[[:alnum:]])?[[:space:]]+[[:alnum:]]([[:alnum:][:punct:]]*[[:alnum:]])?[[:space:]]+[[:digit:]]+' data
example for 1
useful when 1
,boy wonder 1
,hary-horse wondered 2
O'Reilly Books 23
Coelecanths, Dodos Etc 19
$
根据需要删除for. However 1
行。