删除包含两个字符串匹配项的行

Che*_*tar 6 text-processing

如何从以下文件(第 2 行和第 4 行)中删除所有包含defANDjkl的行?我希望匹配也适用于字段的子字符串匹配。文件中的字段以空格分隔。

$ cat test2.txt 
1. abc def ghi
2. def ghi jkl
3. jkl mno pqr
4. jkl def stu
5. vwx yza bcd
Run Code Online (Sandbox Code Playgroud)

我设法使用布尔值OR( \|)来做到这一点:

$ sed '/def.*jkl\|jkl.*def/d' test2.txt 
1. abc def ghi
3. jkl mno pqr
5. vwx yza bcd
Run Code Online (Sandbox Code Playgroud)

有没有更简单的 boolean 语法AND,比如$ sed '/defANDjkl/d'

我试过sed '/def&jkl/d', sed '/def&&jkl/d',sed '/def\&jkl/d'sed '/def\&\&jkl/d',但没有任何效果。

Adm*_*Bee 11

由于您声明 substring-match 也将构成删除标准,因此以下awk程序应该可以工作:

~$ awk '!(/def/ && /jkl/)' test.txt
1. abc def ghi
3. jkl mno pqr
5. vwx yza bcd
Run Code Online (Sandbox Code Playgroud)

这将只打印不满足条件“行匹配defjkl”的行。

如果必须的话sed,您可以修改Stéphane Chazelas 的这个答案

~$ sed -e '/def/!b' -e '/jkl/d' test.txt 
1. abc def ghi
3. jkl mno pqr
5. vwx yza bcd
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 11

有了sed具体而言,你可以这样做:

sed -e '/def/!b' -e /jkl/d
Run Code Online (Sandbox Code Playgroud)

其中第一个e上的表达b牧场出(它打印,因为我们没有通过行-n选项),如果def不是(!)发现,第二个d如果eletesjkl被发现。所以,最后如果两个线仅删除defjkl发现。

要推广到任意数量的正则表达式,您可以执行以下操作:

sed '
  /regexp1/!b
  /regexp2/!b
  /regexp3/!b
  d'
Run Code Online (Sandbox Code Playgroud)

请注意,这\|不是标准的基本正则表达式(BRE) 运算符。很少有sed实现支持它。标准 BRE 既没有 OR 也没有 AND 运算符。标准 ERE(扩展的正则表达式,由sed -E许多sed实现支持)确实支持 OR ( |) 但不支持AND。

ast-open实现在使用or启用的增强正则sed表达式中确实有一个 AND 运算符 ( &) ,但您需要:-A-X

sed -A '/.*def.*&.*jkl.*/d'
Run Code Online (Sandbox Code Playgroud)

作为A&BA和都匹配的字符串的匹配项B

对于sed支持类似 perl 的正则表达式的实现(如sed -Past-open 或sed -Rwith ssed),您可以使用前瞻运算符:

sed -P '/^(?=.*def)(?=.*jkl)/d'
Run Code Online (Sandbox Code Playgroud)

它匹配行首,前提是它后跟 ( (?=...))后跟任意数量的字符 ( .*) 后跟,def并且后跟任意数量的字符后跟jkl.

grep这种支持的实现-Psed虽然更多,所以:

grep -vP '^(?=.*def)(?=.*jkl)'
Run Code Online (Sandbox Code Playgroud)

会更便携。


ter*_*don 10

您也可以改用 perl。在这种情况下,它的语法比sed以下更容易理解:

$ perl -ne 'print unless /def/ && /jkl/' test2.txt 
1. abc def ghi
3. jkl mno pqr
5. vwx yza bcd
Run Code Online (Sandbox Code Playgroud)

或者

$ perl -ne '/def/ && /jkl/ || print' test2.txt 
1. abc def ghi
3. jkl mno pqr
5. vwx yza bcd
Run Code Online (Sandbox Code Playgroud)

甚至:

$ perl -ne '(/def/ && /jkl/) ? next : print' test2.txt 
1. abc def ghi
3. jkl mno pqr
5. vwx yza bcd
Run Code Online (Sandbox Code Playgroud)