首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用带有负前瞻性断言的grep

使用带有负前瞻性断言的grep
EN

Stack Overflow用户
提问于 2021-05-31 21:38:38
回答 4查看 1.9K关注 0票数 2

我有同样的问题,在这篇文章中,然而regex并不适用于我,在bash。RegExp排除,寻找一个没有后面跟着另一个单词

我想包括csv文件中包含单词"Tom“的所有行,除非后面是”拇指“。

  • 包括:汤姆坐在海边。
  • 不包括:汤姆拇指坐在海边。
  • 包括:汤姆和汤姆拇指坐在海边。

regex Tom(?!\s+Thumb)在regex101.com上试运行。

但我试过所有这些变体,但都没有用。我错过了什么,我怎么才能解决这个问题?我在苹果电脑上。

cat inputfile.csv | grep Tom(?!\s+Thumb) > Tom.csv

cat inputfile.csv | egrep Tom(?!\s+Thumb) > Tom.csv

cat inputfile.csv | egrep “Tom(?!\s+Thumb)” > Tom.csv

cat inputfile.csv | grep -E Tom(?!\s+Thumb) > Tom.csv

cat inputfile.csv | grep -E “Tom(?!\s+Thumb)” > Tom.csv

EN

回答 4

Stack Overflow用户

发布于 2021-05-31 21:46:52

--你不能用POSIX在这里做这件事。

POSIX扩展正则表达式中没有负面的前瞻性断言,这是grep -E激活的语法。

最接近的方法是将两个单独的正则表达式结合起来,一个是正匹配,另一个是负匹配:

代码语言:javascript
复制
grep -we 'Tom' inputfile.csv | grep -wvEe 'Tom[[:space:]]Thumb'

grep -v排除了与给定表达式匹配的任何行;因此,在这里,我们首先搜索Tom,然后删除Tom Thumb

然而,匹配Tom and Tom Thumb sat by the seashore的意图使得这是不可行的。简而言之:你不能用标准的grep做你想要的事情,除非它有grep -P来使你原来的语法有效。在这种情况下,您可以使用:

代码语言:javascript
复制
grep -Pwe 'Tom(?!\s+Thumb)' <inputfile.csv >Tom.csv

一次攻击可能是临时替代

假设您有可用的uuidgen (它似乎存在于大Sur中)以生成一个临时的、不可预测的信号:

代码语言:javascript
复制
uuid=$(uuidgen)
sed -e "s/Tom Thumb/$uuid/g" <inputfile.csv \
  | grep -we 'Tom' \
  | sed -e "s/$uuid/Tom Thumb/g" >tom.csv
票数 7
EN

Stack Overflow用户

发布于 2021-05-31 23:11:44

Perl解决方案如何:

代码语言:javascript
复制
perl -ne 'print if /Tom(?!\s+Thumb)/' inputfile.csv > Tom.csv

Perl显然支持PCRE并在Mac上预装。

  • -n选项主要等同于sed的选项。它抑制了自动打印。
  • -e选项通过放置即时代码来启用一行代码。
  • 代码print if /pattern/是一个用来打印匹配行的成语,它可以替代grep命令。
票数 2
EN

Stack Overflow用户

发布于 2021-06-01 18:17:33

保持简单,只需使用awk,例如在每个Unix框中使用任何shell中的任何awk:

代码语言:javascript
复制
$ awk '{orig=$0; gsub(/Tom Thumb/,"")} /Tom/{print orig}' file
Include: Tom sat by the seashore.
Include: Tom and Tom Thumb sat by the seashore.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67780479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档