当需要比较文件中不同行中的多个字符时,如何删除文件中的行?

当需要比较文件中不同行中的多个字符时,如何删除文件中的行?

例如:

文件 xx.txt 的内容是:

Hi
How Are You Doing
Its Been Long Time
Hope Everything Is Fine

所以如果我需要删除包含单词的行正在做或者美好的

文件 xx.txt 的输出必须如下所示:

Hi
Its Been Long Time

是否可以使用单个sedawk命令来完成此操作?

答案1

尝试这个,

打印输出:

sed '/Doing\|Fine/d' xx.txt 

要直接在文件中删除该行:

sed -i '/Doing\|Fine/d' xx.txt 

答案2

grep -vE "Doing|Fine" xx.txt 

它将打印所有没有“Doing and Fine”字样的行

答案3

awk '$0 !~/Fine|Doing/' i.txt  

输出

Hi
Its Been Long Time

答案4

要删除所有包含单词DoingFine的行,您可以使用grep以下方式:

grep -Fw -v -e 'Doing' -e 'Fine' file

-F选项grep使用给定的表达式作为字符串而不是作为正则表达式, while-w使其匹配整个单词(而不是其他单词的子字符串,例如DoingsFines)。该-v选项反转测试的含义,以便从输出中删除与给定表达式匹配的行。这两个字符串由 给出-e,它用于给出要查询的表达式(此选项通常被省略,但这里需要,因为我们有两个)。


有了sed,你可以做

sed -e '/\<Doing\>/d' -e '/\<Fine\>/d' file

或者

sed '/\<Doing\>/d; /\<Fine\>/d' file

或者

sed -E '/\<(Doing|Fine)\>/d' file

其中每一个都将两个字符串作为单词进行匹配。\<和特殊模式\>分别匹配单词开头和结尾的零宽度空格(单词字符和非单词字符之间的空格)。对于 GNU sed,您可以使用\b和 来代替\<\>

最后一个sed命令使用交替来匹配任一单词。替换是扩展正则表达式的一项功能,因此我们-E在命令行上启用这些功能。

在所有情况下,模式都会与输入的每一行进行匹配,如果匹配,则使用命令将其删除d。所有其他行均被打印。

相反,打印所有不匹配的行并忽略其余行,可以通过以下方式完成

sed -n -E '/\<(Doing|Fine)\>/!p' file

即,关闭数据的默认输出-n,然后仅打印 ( ) 与 ( ) 模式p不匹配的行。!


代码awk看起来像非常相似使用扩展正则表达式的sed代码,至少在使用 GNU 的情况下awk(它理解\<and \>):

awk '!/\<(Doing|Fine)\>/' file

或者

awk '!/\<Doing\>/ && !/\<Fine\>/' file

它们都尝试将两个单词与输入数据进行匹配,如果单词存在,则不会打印数据。

您也可以使用index()in 中的函数awk,但这也会找到单词作为子字符串(就像使用一样/(Doing|Fine)/):

awk '!index($0, "Doing") && !index($0, "Fine")' file

index($0, string)string如果在(整行)中找不到 则返回零$0,因此用 否定结果!会给你一个真的如果未找到该字符串,则返回该值。

最常用的方法awk是分别检查每个字段:

awk '{ for (i = 1; i <= NF; ++i) if ($i == "Doing" || $i == "Fine") next; print }' file

这会针对这两个单词测试每个字段,如果找到其中一个单词,则立即跳到下一个输入行。否则,将打印该行。

如果文本中出现/\<(Doing|Fine)\>/类似的单词,这会产生不同的结果。A-Doing循环不会发现它(因为字段是按空格划分的),但正则表达式会发现它(因为-是非单词字符)。

相关内容