如何使用 SED 删除两个字符之间的所有内容?

Jon*_*ker 1 linux bash sed

如何使用 sed 删除两个字符之间的所有文本...

例如:

00arbez+15611@hotmail.com
00aryapan+kee45j@rediffmail.com
asghrsha+hfcdedd@yahoo.com
Run Code Online (Sandbox Code Playgroud)

我想删除电子邮件中的文本 + 到 @。(连+都需要删掉,@符号要保留)

我使用了以下命令:

sed -e 's/\(+\).*\(@\)/\1\2/' FILE.txt > RESULT.txt
Run Code Online (Sandbox Code Playgroud)

但是文件的输出中包含“+”号。例如:asghrsha+@yahoo.com

我想要以下输出:

00arbez@hotmail.com
00aryapan@rediffmail.com
asghrsha@yahoo.com
Run Code Online (Sandbox Code Playgroud)

有人可以帮我修改上面的 sed 命令吗?

Kam*_*ski 5

我将从原始命令开始,而不是从头开始构建。在这种情况下,从头开始构建是一种很好的方法,但在理解原始命令和根据需要调整命令时可以采取的步骤仍然具有教育价值。

原命令的核心:

sed -e 's/\(+\).*\(@\)/\1\2/'
Run Code Online (Sandbox Code Playgroud)

该表达式采用一种形式s/pattern/replacement/,意思是“搜索pattern并替换为replacement”。/是这里的分隔符。

你的pattern\(+\).*\(@\)。如果它是,它的匹配功能将是相同的+.*@\( \)在 的上下文replacement中将某些内容括起来,我们将得到它)。模式的+.*@意思是“文字+后跟(几乎)任何字符 ( .) 重复零次或多次 ( *),然后是文字@“。

Note+匹配第一个可能的+并且*是贪婪的,所以这个匹配从第一个+到最后一个@。在您的具体情况下可能无关紧要,但有时仍然非常重要。

你的替代品是\1\2。它的意思是“第一个匹配的内容,\( \)然后是第二个匹配的内容\( \)”。你的第一个\( \)其实是\(+\),它匹配+你想要摆脱的。

明确地说:这些\( \)组出现在模式中的原因(所以模式不仅仅是+.*@)是它们定义了被称为\1和 的片段\2

因此,如果您不想+被打印,对原始命令的最小更改将是省略\1,因为这是+在您的情况下打印的确切部分。

sed -e 's/\(+\).*\(@\)/\2/'
Run Code Online (Sandbox Code Playgroud)

但你并不需要\( \)各地+在模式,因此可以简化:

sed -e 's/+.*\(@\)/\1/'
Run Code Online (Sandbox Code Playgroud)

注意\2变成了\1因为\(@\)现在是第 1\( \)组。此外,由于它只能匹配@,您可以使用文字@代替\1

sed -e 's/+.*\(@\)/@/'
Run Code Online (Sandbox Code Playgroud)

但现在你根本不需要\( \)。命令变为:

sed -e 's/+.*@/@/'
Run Code Online (Sandbox Code Playgroud)

然后你记得*是贪婪所以.*可能包括 (extra) +or/and @。假设你不想要这个。你需要变成.匹配任何东西但@or 的东西+

sed -e 's/+[^@+]*@/@/'
Run Code Online (Sandbox Code Playgroud)

这正是另一个答案给你的。有点经验的sed用户会从头开始构建这个解决方案。如您所见,可以以合乎逻辑的方式逐步减少原始命令,并获得相同的解决方案。