sed - 删除第三个字段中包含“hotmail”的行

sed - 删除第三个字段中包含“hotmail”的行

我正在尝试从 .txt 文件中删除第三个字段中包含单词 hotmail 的所有电子邮件。我目前正在尝试使用以下内容,但它只会删除一些行。我不知道为什么

sed -i '/^[^,]*,[^,]*,[^,]*hotmail/d' *.txt

下面是未删除的行之一

"field1","field2.","[email protected]","whoeditedoutn.com","NeditedoutOW.COM|NeditedoutW.COM","editedout",""
"foo,bar","baz,qux","[email protected]","whoeditedoutn.com","NeditedoutOW.COM|NeditedoutW.COM","editedout",""

有人能给我正确的命令吗?另外,如果可能的话,命令该单词同时具有大写和小写hotmailHoTmAiL任何其他变体。

答案1

由于这是 CSV 文件,字段 1 和 2 可能包含逗号。因此正则表达式匹配将不起作用。您需要一个合适的 CSV 解析器。这是一个例子

ruby -rcsv -ne 'row = CSV::parse_line($_); puts $_ unless row[2] =~ /hotmail/i' file

更新:该 ruby​​ 命令确实不会更改文件。上面的 sed 命令也没有。要将更改保存回文件,请使用该-i选项。使用您的 Pastebin 数据:

wc -l file
ruby -rcsv -i -ne 'row = CSV::parse_line($_); puts $_ unless row[2] =~ /hotmail/i' file
wc -l file
  22 file
  20 file

Perl 也有一个 CSV 模块,但不是标准的,从 CPAN 获取-- 错误处理未实现

perl -MText::CSV -le '
  $csv = Text::CSV->new({ binary=>1, always_quote=>1 });
  open $fh, "<", shift(@ARGV);
  while ($row = $csv->getline($fh)) {
    $csv->print(STDOUT, $row) unless $row->[2] =~ /hotmail/i;
  }
' file

答案2

当您询问sed解决方案时,

sed -n -e '/^"[^,]*","[^"]*",".*@hotmail/Ip' file

这里我只是打印要删除的行。恢复到原来的选择,完全按照您的意愿行事。更改/Ip/Id并更改-n-i

/I提供不区分大小写的搜索

第二个字段使用[^"]而不是逗号,这样内部有逗号的字段就不会被分割。

我已将引号添加到字段中,并在域名前添加 @,使其看起来更像电子邮件地址。

更新:此版本确保 @hotmail.com 后跟 2 个电子邮件地址。 ie是第一个上线的。

这会在第三列搜索 hotmail 地址

sed -n -e '/^"[^"]*","[^"]*","[email protected]",.+@.+,.+@.+$/Ip' file

这适用于第三列中任何位置的 hotmail,因此可以与您在 Pastebin 中的测试数据配合使用。

sed -n -e '/^"[^"]*","[^"]*",".*hotmail.+",.+@.+,.+@.+$/Ip' file

更新2:

我已将正则表达式简化为:

sed -n -e '/^("[^"]*",){2}"[^"]*hotmail[^"]*"/Ip'

答案3

使用csvkit:

csvgrep -c 3 -i -r '(?i)hotmail' file.csv

这假设file.csv有一个标题行。

相关内容