懒惰的 Grep -P:如何只显示第一场比赛



我只需要打印每行的第一场比赛。

我的文件包含如下文本:

cat t.txt
abcsuahrcb
abscuharcb
bsaucharcb
absuhcrcab

他是我正在尝试的命令:

cat t.txt | grep -oP 'a.*?c'

它给出:

abc
ahrc
absc
arc
auc
arc
absuhc

我需要它返回:

abc
absc
auc
absuhc

这些是每行的第一个可能的匹配项。

任何其他替代方案,如sed和aws都可以工作,但不是需要在Ubuntu上安装的东西。

Perl 来救援:

perl -lne 'print $1 if /(a.*?c)/' t.txt
  • -n逐行读取输入,为每个输入运行代码;
  • -l从输入行中删除换行符并将它们添加到输出中;
  • 代码尝试匹配a.*?c,如果匹配,它将结果存储在 $1 中;
  • 由于没有循环,因此每行只尝试一场比赛。

第四只鸟的答案的sed变体:

$ sed -En 's/^[^a]*(a[^c]*c).*/1/p' t.txt
abc
absc
auc
absuhc

哪里:

  • -En- 启用扩展正则表达式支持,禁止自动打印模式空间
  • ^[^a]*- 从行首匹配所有未a的后续字符
  • (a[^c]*c)- (第 1 个捕获组)匹配字母a加上所有未c后跟c的后续字符
  • .*- 匹配行的其余部分
  • 1/p- 打印第一个捕获组的内容

一个awk想法:

$ awk 'match($0,/a[^c]*c/) { print substr($0,RSTART,RLENGTH)}' t.txt
abc
absc
auc
absuhc

哪里:

  • 如果我们找到匹配项,则match()调用为非零(即"true"),因此...
  • 打印由RSTART/RLENGTH变量定义的substr(由成功的match()调用自动填充)

使用grep您可以使用否定字符类将模式编写为从第一个a到第一个c的匹配。

使用 Perl 兼容正则表达式的-P,您可以使用K来忘记到目前为止匹配的内容。

请注意,您不必使用cat,但您可以在末尾添加文件名。

grep -oP '^[^a]*Ka[^c]*c' t.txt

模式匹配:

  • ^字符串开头
  • [^a]*可选匹配除a之外的任何字符
  • K忘记到目前为止匹配的内容
  • a字面意思匹配
  • [^c]*可选匹配除c以外的任何字符
  • c字面意思匹配

输出

abc
absc
auc
absuhc

另一个具有gnu-awk和相同模式的选项,只是现在使用和打印捕获组 1 值:

awk 'match($0,/^[^a]*(a[^c]*c)/, a) { print a[1]}' t.txt

相关内容

  • 没有找到相关文章

最新更新