Awk 如果该行包含另一个文件行中的确切字符串,请删除该行

Awk 如果该行包含另一个文件行中的确切字符串,请删除该行,awk,sed,grep,Awk,Sed,Grep,我有一个大文件,希望删除文件中包含另一个文件中列出的确切字符串的任何行。但是,字符串必须完全匹配(很抱歉,我不知道如何更好地描述它) 文件如下: one@email.com,name,surname,city,state two@email.com,name,surname,city,state three@email.com,name,surname,city,state anotherone@email.com,name,surname,city,state 下面是要过滤的示例列表: on

我有一个大文件,希望删除文件中包含另一个文件中列出的确切字符串的任何行。但是,字符串必须完全匹配(很抱歉,我不知道如何更好地描述它)

文件如下:

one@email.com,name,surname,city,state
two@email.com,name,surname,city,state
three@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state
下面是要过滤的示例列表:

one@email.com
three@email.com
所需输出为:

two@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state
我已尝试使用以下方法进行此操作:

grep -v -f 2.txt 1.txt > 3.txt
但是,这会产生以下输出:

two@email.com,name,surname,city,state
我想它这样做是因为“anotherone@email.com“包含”one@email.com". 我已经寻找了一种包含行开头的方法,但并没有找到任何合适的方法


除了grep,我也愿意做其他事情,我使用grep是因为我无法找到其他方法。

如果您只喜欢打印第一个文件中的行,而第一个字段中的
不包含第二个文件中的数据,那么应该这样做:

$cat file
one@email.com,name,surname,city,state
two@email.com,name,surname,city,state
three@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state
$cat filter
one@email.com
three@email.com

awk -F, 'NR==FNR {a[$0]++;next} !($1 in a)' filter file
two@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state
对于
过滤器中的每一行
这将创建一个数组
a
,其名称和值为
1

a[one@email.com]=1
a[three@email.com]=1

然后,
awk
文件
中针对数组逐行测试,给出

a[one@email.com]=1
a[two@email.com]=
a[three@email.com]=1
a[anotherone@email.com]=
然后打印
文件中的所有行,不带
1

two@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state

如果您只想打印第一个文件中
在第一个字段中不包含第二个文件数据的行,则应执行以下操作:

$cat file
one@email.com,name,surname,city,state
two@email.com,name,surname,city,state
three@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state
$cat filter
one@email.com
three@email.com

awk -F, 'NR==FNR {a[$0]++;next} !($1 in a)' filter file
two@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state
对于
过滤器中的每一行
这将创建一个数组
a
,其名称和值为
1

a[one@email.com]=1
a[three@email.com]=1

然后,
awk
文件
中针对数组逐行测试,给出

a[one@email.com]=1
a[two@email.com]=
a[three@email.com]=1
a[anotherone@email.com]=
然后打印
文件中的所有行,不带
1

two@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state
对于这种特殊情况——通过构建一个关联数组(以过滤线作为索引)来处理第一个文件。在后续文件中,测试给定行是否不在数组索引中——模式的默认操作是打印

awk -F, -v OFS=, '
    BEGIN   { split("", m) }
    NR==FNR { m[$0] = ""; next }
    !($1 in m)
' filter.txt file.txt
但是。。。如果我们希望过滤行中任何位置出现的字符串(无约束的精确匹配),我们需要做一些不那么聪明、更粗暴的事情:

awk '
    BEGIN {
        split("", m)
        n=0
    }
    NR==FNR {
        m[n++] = $0
        next
    }
    {
        for (i=0; i<n; ++i) {
            if (index($0, m[i]))
                next
        }
        print
    }
' filter.txt file.txt
awk'
开始{
拆分(“,m)
n=0
}
NR==FNR{
m[n++]=$0
下一个
}
{
对于(i=0;i对于这种特殊情况——通过构建一个关联数组(以筛选行作为索引)来处理第一个文件。在后续文件中,测试给定行是否不在数组索引中——模式的默认操作是打印

awk -F, -v OFS=, '
    BEGIN   { split("", m) }
    NR==FNR { m[$0] = ""; next }
    !($1 in m)
' filter.txt file.txt
但是…如果我们想过滤行中任何位置出现的字符串(无约束的精确匹配),我们需要做一些不那么聪明、更粗暴的事情:

awk '
    BEGIN {
        split("", m)
        n=0
    }
    NR==FNR {
        m[n++] = $0
        next
    }
    {
        for (i=0; i<n; ++i) {
            if (index($0, m[i]))
                next
        }
        print
    }
' filter.txt file.txt
awk'
开始{
拆分(“,m)
n=0
}
NR==FNR{
m[n++]=$0
下一个
}
{

对于(i=0;i假设您的输入文件包含
three@gmail.com
three@email.com
(可能是打字错误)


-w,--word regexp-
表达式作为单词搜索(假设输入文件包含
three@gmail.com
three@email.com
(可能是打字错误)


-w,--word regexp-
表达式作为单词搜索(好像被
[[:three@email.com != three@gmail.comIf您可以使用GNU grep添加选项
-w
。three@email.com != three@gmail.comIf您使用GNU grep add option
-w
。这可能有点危险,因为它不仅在文件的第一个字段中搜索筛选器,而且在行的任何地方都搜索。因此,如果在末尾找到该单词,它也会删除comp删除行。例如,它将删除此行
anotherone@email.com,姓名,姓氏,城市,州,three@email.com
@Jotne,OP没有说明“在文件的第一个字段中”搜索的规则是的,这就是为什么OP应该阅读我的评论,如果在行中的任何位置找到筛选数据,并且他只查找第一个字段,则此解决方案确实会删除该行。您的解决方案可能适合OP。@Jotne ok,让我们等待OP的反应。对于延迟回复,请担心-电子邮件仅在第一个字段中找到,因此它可以正常工作预期。但是,由于输入的大小,这会很快产生内存错误。这可能有些危险,因为它不仅在文件的第一个字段中搜索筛选器,而且在行的任何地方都搜索。因此,如果在末尾找到该单词,它也会删除整行。例如,它将删除这一行
anotherone@email.com,不适用我,姓氏,城市,州,three@email.com
@Jotne,OP没有说明“在文件的第一个字段中”搜索的规则是的,这就是为什么OP应该阅读我的评论,如果在行中的任何位置找到筛选数据,并且他只查找第一个字段,则此解决方案确实会删除该行。您的解决方案可能适合OP。@Jotne ok,让我们等待OP的反应。对于延迟回复,请担心-电子邮件仅在第一个字段中找到,因此它可以正常工作预期。但是,由于输入的大小,这很快就产生了内存错误。在我使用的两个大文件中工作得很好。非常感谢。在我使用的两个大文件中工作得很好。非常感谢。