如何使用 Unix 从一行中删除第二次出现

Posted

技术标签:

【中文标题】如何使用 Unix 从一行中删除第二次出现【英文标题】:How to delete second occurrence from a line using Unix 【发布时间】:2021-02-17 21:23:19 【问题描述】:

我在文件中有以下数据

They used to carry lots of treats
but now they don’t have any sweets.
And so, if you’re in need of candy,
please don’t visit Mrs. Mandy. He is working in office.But will be late from office

例如:

使用以下命令,我得到了作为同一行中的两个关键字的行

grep "Mandy" file.txt | grep "office"

上面的命令作为输出给我下面一行

please don’t visit Mrs. Mandy. He is working in office.But will be late from office

现在从我得到的输出需要删除第二个出现的关键字:office 并在输出下方打印

预期输出:

please don’t visit Mrs. Mandy. He is working in office.But will be late from 

如何实现上述预期输出?

【问题讨论】:

【参考方案1】:

sed 可以使用s/office//2 做到这一点。最重要的是,您可以将整个管道组合成一个命令。

sed -n '/Mandy/s/office//2p' file.txt

解释:

在上面的命令中有 2 个sed 命令。

    /Mandy/ 仅在包含 Mandy 的行上运行下一个命令。

    s/office//2p 删除(s用空字符串替换)office 在这些行中的2第 2 次出现并 prints他们之后。

【讨论】:

您能否详细说明这一点/Mandy/s/office//2p 的解决方案以及为什么给出s @codeholic24 我更新了答案。 s 是一个 sed 命令。【参考方案2】:

我想这就是你要找的:

grep "Mandy" file.txt | grep "office" | grep -oP '.*(?=office)(?=office)'

这使用了正则表达式和积极的前瞻。 它会产生您正在寻找的输出:

please don’t visit Mrs. Mandy. He is working in office.But will be late from

【讨论】:

.*(?=office)(?=office) 等同于.*(?=office) 并且删除第二个office,而只是删除最后一个和之后的所有内容。

以上是关于如何使用 Unix 从一行中删除第二次出现的主要内容,如果未能解决你的问题,请参考以下文章

仅替换模式中的第二次出现

从对象数组中删除第二次出现的对象[重复]

在 Perl 中,如何从文件中删除 ^M?

根据数组中的重复模式更改 SwiftUI 列表中文本字段的第二次出现

c语言中如何在一个字符串中查找/出现的位置?需要第一次出现和第二次出现中间的内容和第二次出现和第三

Bash:从第一次出现字符到第二次出现的子字符串