例如:
文件 xx.txt 的内容是:
Hi
How Are You Doing
Its Been Long Time
Hope Everything Is Fine
所以如果我需要删除包含单词的行正在做或者美好的。
文件 xx.txt 的输出必须如下所示:
Hi
Its Been Long Time
是否可以使用单个sed
或awk
命令来完成此操作?
答案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
要删除所有包含单词Doing
或Fine
的行,您可以使用grep
以下方式:
grep -Fw -v -e 'Doing' -e 'Fine' file
该-F
选项grep
使用给定的表达式作为字符串而不是作为正则表达式, while-w
使其匹配整个单词(而不是其他单词的子字符串,例如Doings
或Fines
)。该-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
循环不会发现它(因为字段是按空格划分的),但正则表达式会发现它(因为-
是非单词字符)。