Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
搜索一个文件';在另一个文件(Mac/Linux/Unix命令行)中为部分匹配设置s行_Linux_Email_Unix_Csv_Grep - Fatal编程技术网

搜索一个文件';在另一个文件(Mac/Linux/Unix命令行)中为部分匹配设置s行

搜索一个文件';在另一个文件(Mac/Linux/Unix命令行)中为部分匹配设置s行,linux,email,unix,csv,grep,Linux,Email,Unix,Csv,Grep,我有两个文本文件。一个是带有名称、电子邮件地址和其他字段的CSV文件。另一个只包含电子邮件地址。有没有一种简单的方法可以搜索CSV文件并只输出“电子邮件地址列表”文件中不匹配的行 如果有人能给我指出正确的方向,我很乐意找出答案,并把答案贴给其他人。我的猜测是我需要用cat和grep做些什么,但是我的Google搜索(和堆栈溢出搜索)以及在命令行上的努力到目前为止都没有效果 虽然我可以在Excel甚至SQL中轻松地完成同样的事情,但这将是一个持续的需求,因此shell命令会更好,因为不需要下载CS

我有两个文本文件。一个是带有名称、电子邮件地址和其他字段的CSV文件。另一个只包含电子邮件地址。有没有一种简单的方法可以搜索CSV文件并只输出“电子邮件地址列表”文件中不匹配的行

如果有人能给我指出正确的方向,我很乐意找出答案,并把答案贴给其他人。我的猜测是我需要用cat和grep做些什么,但是我的Google搜索(和堆栈溢出搜索)以及在命令行上的努力到目前为止都没有效果

虽然我可以在Excel甚至SQL中轻松地完成同样的事情,但这将是一个持续的需求,因此shell命令会更好,因为不需要下载CSV文件、转换为Excel或导入数据库的步骤

提前感谢您的指导-
Chris

您可以使用
awk
完成以下操作:

awk -F, 'NR == FNR {file1[$1]; next} !($2 in file1)' /path/to/file1 /path/to/file2
awk -F, 'NR == FNR {file1[$1]; next} 
         { if($2~/^".*"$/) { email=substr($2,2,length($2)-2) } else { email=$2 } 
           if(!(email in file1)) {print $0} }' /path/to/file1 /path/to/file2
其中
file1
包含的是仅包含电子邮件地址的文件,
file2
是CSV文件

awk
程序加载数组中的所有电子邮件地址,然后检查
file2
中的第二个字段在数组中是否匹配(如果不匹配,则打印
file2
中的整个对应行-这部分是隐式的)。程序假定字段分隔符实际上是逗号;如果不是,请使用
-F
选项设置实际分隔符。该程序还假设电子邮件地址存储在CSV文件的第二个字段中;如果不是,请将
$2
更改为
$x
,其中
x
是字段号(从1开始)

您可能会在电子邮件地址列表中遇到问题,因为它存储在内存中很长

例如:

file1:
email2
email3

file2:
name1,email1,other1,otherother1
name2,email2,other2,otherother2
name3,email3,other3,otherother3
name4,email4,other4,otherother4

output:
name1,email1,other1,otherother1
name4,email4,other4,otherother4
更新:如果CSV可以包含引用的电子邮件地址,则应按如下方式删除引用:

awk -F, 'NR == FNR {file1[$1]; next} !($2 in file1)' /path/to/file1 /path/to/file2
awk -F, 'NR == FNR {file1[$1]; next} 
         { if($2~/^".*"$/) { email=substr($2,2,length($2)-2) } else { email=$2 } 
           if(!(email in file1)) {print $0} }' /path/to/file1 /path/to/file2

fgrep-v-f filewithaddresslist filetosearch.CSV这可能导致错误的结果,因为您没有将电子邮件地址与CSV中的电子邮件字段匹配,而是与整个CSV行匹配。我可能做错了什么,但该命令的结果输出与原始文件完全匹配@isedev-对,我需要在给定行的子集中找不到电子邮件的项目列表。我今天有一个简单的解决方案,但我希望能够为将来编写脚本。@ChrisLarkin:我给你的解决方案不起作用?嗨,我刚刚看到了!非常感谢你,我会尽快测试,只要我能回到那个系统并发布一个回复。这个命令,虽然几乎是即时的,而fgrep行超过一个小时,得到了相同的结果。输出文件包含每一行。电子邮件字段是第一个,因此我相应地更改了$2;但是,有些字段用引号括起来。这可能是问题所在吗?我有一个名为PreferredEmails.txt的文件(每行包含一个电子邮件地址)和另一个名为List.csv的文件。这是命令:awk-F,'NR==FNR{PreferredEmails[$0];next}!(PreferredEmails中$1)'PreferredEmails.txt List.csv>NewList.csv,csv文件:
“电子邮件地址”、“名字”、“姓氏”、MAGE_客户组、电子邮件类型、会员评级、选项时间、选项IP、确认时间、确认IP、纬度、经度、GMTOFF、DSTOFF、时区、抄送、地区、上次更改、LEID、EUIDboln@gmail.com,John,Boln,General,html,2,,,“2012-12-08 21:36:43”,24.148.81.237,“2012-12-08 21:36:43”,57169513015A8038D1droobie@yahoo.com,Larry,Baxter,,html,2,,,“2012-12-12 03:14:15”,69.160.44.110,44.8141000,-68.7786000,-5,-4,美国/蒙特利尔,美国,美国,ME,“2013-05-22 12:11:24“,57169677,21e75a3a40
电子邮件列表:
johnj234@chicago.com boln@gmail.com layers@yahoo.com
FYI我是新来这里发帖的,所以我不知道为什么这些都显示在一行上。在文件中,每个电子邮件地址都以CRLF结尾。感谢您的帮助@isedev-I减小了文件的大小(字段数),并且您的示例成功了。现在,我们将在没有自动化的情况下处理这个问题,因为减少字段需要时间,我已经花了相当多的时间进行测试,这否定了我们在这个月任务中获得的任何好处。