如果在文本文件 ( )中找到input.txt
两个模式 (string1
和) ,我想从文本文件中删除一行string2
相同的行,使用sed
.
我正在尝试:
sed -i "/\b\(string1\|string2\)\b/d" input.txt
,但这正在删除包含string1
OR 的行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
这会删除同时包含 和 的行string1
,string2
无论顺序如何(甚至可能会重叠,就像在包含 的行中查找foobar
in时一样)。barbaz
foobarbaz
-i
上面是一个 GNU 扩展。另一个特定于 GNU 的解决方案 1:
awk -i /usr/share/awk/inplace.awk '!(/string1/ && /string2/)' file.txt
可移植的是,您可能会perl
在这里使用:
perl -ni -e 'print unless /string1/ && /string2/'
^不使用-i inplace
as尝试首先从当前工作目录gawk
加载inplace
扩展(asinplace
或),有人可能已经在其中植入了恶意软件。随系统提供的扩展inplace.awk
的路径可能会有所不同,请参阅输出inplace
gawk
gawk '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 barbaz
和foobar foobaz barbaz
。
注意,使用 Raku 正则表达式能:overlap
使用(或:ov
) 参数/副词检测两个重叠的字符串。请参阅下面的第一个链接。
https://docs.raku.org/language/regexes#Overlap
https://docs.raku.org/language/regexes
https://raku.org