从选定字符向后提取文本

从选定字符向后提取文本

我有一个包含以下几行的文件:

handleNewConnection:: User [email protected] has 2 active nodes
handleNewConnection:: User [email protected] has 2 active nodes
handleNewConnection:: User [email protected] has 2 active nodes
handleNewConnection:: User [email protected] has 2 active nodes

系统必须查找“@”(选定的字符),然后从“@”符号向后提取字符串。正如您所注意到的,它可以包含数字或字母字符,并且长度不是恒定的。

grep -o '[^"]@' /tmp/has2.txt

我得到:

m@
2@
1@
g@

1)有谁知道是否可以通过这种方式获得第二个文本文件?

langfordm
bas102
bah001
mattleg

2) 有谁知道我是否可以单独使用 1) 中生成的名称作为另一个进程的输入?

答案1

grep与 PCRE ( ) 一起使用-P

$ grep -Po '.*\s\K[^@]+(?=@)' file.txt
langfordm
bas102
bah001
mattleg

或者使用 GNU sed

$ sed -r 's/.*\s([^@]+)@.*/\1/' file.txt 
langfordm
bas102
bah001
mattleg

显然,您可以在另一个进程中使用结果,这取决于下一个进程如何接收输入。根据这一点,您可以创建一个数组或将结果直接传递到下一个进程的 STDIN 上。

答案2

P使用erl 兼容选项非常容易:

grep -Po '\w+(?=@)' file

其中\w匹配任何单词字符,并且(?=...)因此称为展望正则表达式。

输出:

langfordm
bas102
bah001
mattleg

答案3

有几种方法。最简单的方法是使用正则表达式模式匹配

grep -io '[a-z0-9_.]*@[a-z0-9_.]*'

这将匹配并打印最长的字符串,包括

  • or或or*范围内的零个或多个 ( ) 不区分大小写的字符a-z0-9_.
  • 正是一个@
  • or或or*范围内的零个或多个 ( ) 不区分大小写的字符a-z0-9_.

然后把@domain部分分开

cut -d@ -f1

所以完整的线路是

grep -io '[a-z0-9_.]*@[a-z0-9_.]*' /tmp/file.txt | cut -d@ -f1

另一种方法是使用前瞻 PCRE,它允许一步grep打印模式的用户名部分。这很难做到正确,但它消除了上面示例中username@domain的需要cut

grep -Pio '\S+(?=@\S+)'

这意味着

  • 匹配一个或多个 ( +) 非空格字符 ( \S)
  • 后跟模式@和一个或多个 ( +) 非空格字符 ( \S)

答案4

对于任何版本的sed,使用基本正则表达式:

sed -e 's/.* \([^@]\+\)@.*/\1/' /tmp/has2.txt

至于你的第二个问题,你可以总是使用以任何方式键入、提取或生成的数据作为另一个进程的输入,只要:

  1. sed它采用其他进程可以使用的格式(或者可以使用、awkperl和/或其他常用工具转换为该格式)

  2. 另一个进程能够从标准输入或从任意一个或多个文件获取输入 - 即没有硬编码为仅从特定位置的一个特定文件获取输入......即使如此,如果您创建/覆盖该特定文件以使其包含您的数据,它仍然可以工作。

这就是 unix 和小工具方法的美妙之处 - 它鼓励您以以数据为中心的方式思考(其中数据是您的,可以使用您选择的工具(包括自定义编写的工具)来做您想做的事情)而不是以应用程序为中心的方式(其中数据属于神奇的黑盒应用程序,您只能通过该特定应用程序操作数据或与数据交互)。

同样重要的是,它鼓励开发人员(包括应用程序开发人员)以同样以数据为中心的方式进行思考。当应用程序开发人员试图通过锁定应用程序中的用户数据来阻碍他们的需求时,用户会将其视为错误和侵犯他们的权利。

相关内容