如果在同一行中找到两个模式,则删除该行

如果在同一行中找到两个模式,则删除该行

如果在文本文件 ( )中找到input.txt两个模式 (string1和) ,我想从文本文件中删除一行string2相同的行,使用sed.

我正在尝试: sed -i "/\b\(string1\|string2\)\b/d" input.txt,但这正在删除包含string1OR 的行string2

答案1

sed -i "/string1.*string2\|string2.*string1/d" input.txt

这将删除 string1 出现在 string2 之前或 string2 出现在 string1 之前的任何行。两个字符串都必须位于该行上,无论顺序如何,才能删除该行。

答案2

sed -ie '/string1/!b' -e '/string2/d' file.txt

这会删除同时包含 和 的行string1string2无论顺序如何(甚至可能会重叠,就像在包含 的行中查找foobarin时一样)。barbazfoobarbaz

-i上面是一个 GNU 扩展。另一个特定于 GNU 的解决方案 1:

awk -i /usr/share/awk/inplace.awk '!(/string1/ && /string2/)' file.txt

可移植的是,您可能会perl在这里使用:

perl -ni -e 'print unless /string1/ && /string2/'

^不使用-i inplaceas尝试首先从当前工作目录gawk加载inplace扩展(asinplace或),有人可能已经在其中植入了恶意软件。随系统提供的扩展inplace.awk的路径可能会有所不同,请参阅输出inplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

答案3

使用(以前称为 Perl_6)

~$ raku -ne '.put unless .match(/ foobar / & / barbaz / ) ;'   file

或者

~$ raku -ne '.put unless grep({ / foobar / & / barbaz / }, $_ ) ;'   file

以上是使用 Raku 完成 OP 任务的两种一般方法。 Raku 中的注释grep与 Perl 中的注释类似grep,只是块后面需要逗号。您也可以使用.grep方法调用来代替,而不必担心$_在括号内写入。

上面的任一代码示例都会删除包含两个字符串的行,无论顺序如何并且无论字符串是否重叠。例如:

输入示例:

1  foo
2  bar
3  baz
4  foobar
5  foobaz
6  barbaz
7  foobar foobaz
8  foobaz barbaz
9  foobar barbaz
10 foobar foobaz barbaz
11 foobaz barbaz foobar
12 barbaz foobar foobaz
13 foobarbaz

示例输出(上面的代码示例):

1  foo
2  bar
3  baz
4  foobar
5  foobaz
6  barbaz
7  foobar foobaz
8  foobaz barbaz

上面的代码删除了第 9 行到第 13 行,包括foobarbaz包含重叠 string1 和 string2 的第 13 行。如果您需要删除按定义顺序出现的字符串(且不重叠),Raku 也可以做到这一点:

~$ raku -ne '.put unless m/foobar .* barbaz/;'  file

上面删除了第 9 行和第 10 行:foobar barbazfoobar foobaz barbaz


注意,使用 Raku 正则表达式:overlap使用(或:ov) 参数/副词检测两个重叠的字符串。请参阅下面的第一个链接。


https://docs.raku.org/language/regexes#Overlap
https://docs.raku.org/language/regexes
https://raku.org

相关内容