.csv 仅保留某些电子邮件地址?

.csv 仅保留某些电子邮件地址?

我有一个很大的 .csv 文件,其中包含我的客户姓名:电子邮件

我还有另一个大的电子邮件列表,它们是此列表的一部分,并且只想保留这些电子邮件。如何从 .csv 文件中删除 X.txt 中没有的所有联系人?

答案1

假设 X.txt 中的电子邮件每行一封,您可以构建一个数组,检查它是否存在,然后打印出匹配的行:

$ awk -F: 'FNR==NR { a[$2] = $0; next } ($1 in a) { print a[$1] }' customers.csv X.txt
Foo Bar:[email protected]
Baz Qux:[email protected]

FNR==NR仅当在第一个文件中时才为真。以下是我用来测试此功能的文件:

$ cat customers.csv 
Foo Bar:[email protected]
Baz Qux:[email protected]
Wibble Wobble:[email protected]
$ cat X.txt 
[email protected]
[email protected]

答案2

如果您不需要电子邮件位于 .csv 文件的特定字段中,而只需要打印文件中包含目标电子邮件之一的那些行,则可以使用grep

grep -wFf emails.txt file.csv > newfile.csv

如果他们确实需要在特定领域,请使用@ChrisDown解决方案。但请注意,csv 文件可能非常复杂。例如,这是一个有效的 csv 行:

field1,"field 2, which can contain commas, is here", field3

对于此类更复杂的文件,您将需要使用 csv 解析器来正确处理它们。例如,在 Perl 中,您可以使用Text::CSV

  1. 安装cpanm(如果你使用 Perl,稍后你会感谢我的)

    $ sudo apt-get install cpanminus
    

    如果您使用的不是基于 Debian 的系统,您应该能够使用您的发行版的包管理器来安装它。

  2. 安装Text::CSV模块

    $ sudo cpanm Text::CSV
    
  3. 解析你的文件

    $ perl -MText::CSV -le '
    
        BEGIN{
            open($f,"emails.txt"); 
            while(<$f>){chomp; $k{$_}++;}
        } 
        $csv=Text::CSV->new({binary=>1}); 
        while ($row = $csv->getline(STDIN)){
          print join",", @$row if defined($k{$row->[2]})
        }' < file.csv
    

相关内容