检查多个csv文件中是否存在字符串并将行写入文件

时间:2018-03-08 12:08:05

标签: python csv if-statement awk match

我得到了这个项目,我想检查两个或多个csv文件中是否存在电子邮件地址。文件的数量可以变化,也可以是它们的前缀,但它们将始终存储在同一目录中。

我需要以下

的帮助
  1. 在两个或多个文件中查找匹配项的方法。
  2. 立即搜索整个目录
  3. 将匹配地址所在的所有行写入新文件。
  4. 指出我可以在脚本中使用它的方向,我可以将它与“if”语句一起使用,并与webb应用程序一起使用。
  5. 我看过

    extracting rows from CSV file based on specific keywords

    但这需要我知道我要找的是哪个电子邮件地址。

    对于那些有时间的人来说,在下面的文章中你可以找到我到目前为止“已经实现”的内容以及原始文件和所需输出的例子。

    将要检查的原始文件的示例。行数可以变化。有时也可以在第1列以外的其他列中找到电子邮件地址。因此,建议使用关键字方法?这是我尚未完成的事情。

    example.csv
    IP ADDRESS, FIRST TIME LOGGED IN, LAST TIME LOGGED IN, USERNAME
    192.168.1.1 , 2018-03-07 11:33:22, 2018-03-07 11:33:28, Federov
    E-MAIL ADDRESS, FIRST TIME LOGGED IN, LAST TIME LOGGED IN, USERNAME, 
    schultz@mail.com, 2018-03-07 09:33:22, 2018-03-07 11:33:28, Boris Becker
    

    对于保存的文件和webb应用程序,所需的结果如下所示。

    Result.csv
    Match
    E-MAIL ADDRESS, FIRST TIME LOGGED IN, LAST TIME LOGGED IN, USERNAME
    schultz@mail.com, 2018-03-07 09:33:22, 2018-03-07 11:33:28, Boris Becker
    schultz@mail.com, 2017-01-07 14:56:12, 2018-01-18 18:44:03, McEnroe
    

    这是我到目前为止所得到的:

    我尝试将“逐步”方法放入字符串中。我在一个文件夹中运行了这个字符串,其中我有两个带有一个匹配地址的.csv文件。但是我收到零,没有,nada ..没有错误信息,文件中没有任何内容。字符串如下所示:

    awk '/E-MAIL/{y=1;next}y' *.csv | awk '{print $1}' FS="," | awk 'FNR==NR{arr[$1];next}$1 in arr{print $1,"match"}' > results.csv
    

    一步一步它可以正常工作,但对于每个文件来说这都是一项艰苦的工作。我还必须创建新文件才能使其正常工作。

    awk '/E-MAIL/{y=1;next}y' file-0A.csv > /test/file-0B.csv`
    awk '{print $1}' FS="," file-0B.csv > /test/file-1A.csv
    awk 'FNR==NR{arr[$1];next}$1 in arr{print $1,"match"}' file-1A.csv file-1B.csv > /test/results.csv
    

    除了荒谬乏味且可能是简单的愚蠢之外,这种方法或至少在当前状态下,只允许在两个文件之间进行匹配,添加第三个将使其看起来像需要找到匹配所有三个文件中都没有任何两个文件......

    此外,当前方法(如果您甚至可以将其称为方法)不允许在执行匹配步骤时将附加信息与电子邮件地址一起使用,因为这将匹配例如日期或时间。我不知道要将此输出用于“if”语句..

    操作系统是具有root权限的Raspian Stretch。

    如果我没有提供任何重要信息,拼写错误或以错误的方式提出此问题,我会道歉。

    非常感谢任何帮助!

3 个答案:

答案 0 :(得分:0)

获取目录中所有文件的列表:

import os
file list = os.listdir()

您需要打开列表中的所有文件,并将所有电子邮件地址写入字典。像这样:

my_dict[e_mail] = my_dict.get(e_mail, 0) + 1

这将为您提供邮件地址发生频率的计数。然后,您可以将所有地址写入您的outfile多次出现。

答案 1 :(得分:0)

这可以在Python 2.x中完成,如下所示:

from itertools import dropwhile
from collections import defaultdict
import glob    
import csv

fieldnames = ['E-MAIL ADDRESS', 'FIRST TIME LOGGED IN', 'LAST TIME LOGGED IN', 'USERNAME']
emails = defaultdict(list)

for csv_filename in glob.glob('*.csv'):
    with open(csv_filename, 'rb') as f_input:
        csv_reader = csv.DictReader(f_input, fieldnames=fieldnames, skipinitialspace=True)
        next(dropwhile(lambda x: x['E-MAIL ADDRESS'] != 'E-MAIL ADDRESS', csv_reader))

        for row in csv_reader:
            emails[row['E-MAIL ADDRESS']].append(row)


with open('output.csv', 'wb') as f_output:
    csv_writer = csv.DictWriter(f_output, fieldnames=fieldnames, extrasaction='ignore')
    csv_writer.writeheader()

    for email, rows in sorted(emails.items()):
        if len(rows) > 1:
            csv_writer.writerows(rows)

这使用glob.glob()函数为您提供.csv个文件的列表。它会将所有电子邮件地址写入output.csv,其中在找到的所有CSV文件中多次查看电子邮件地址。它会跳过所有行,直到找到开始E-MAIL ADDRESS的行。

答案 2 :(得分:0)

以下awk是一次通过程序,应该可以解决这个问题:

 awk '# The BEGIN statement sets the field separator FS
      BEGIN{FS="[[:blank:]]*,[[:blank:]]*"}

      # If the word "E-MAIL" is not found, skip to the next line
      !/E-MAIL/{next}

      # The line contains "E-MAIL"
      { 
        # Find the column of the email
        for(col=1;col<=NF;col++) { if (match($col,"E-MAIL")) break; }
        getline;      # retrieve the next line 
        email=$col;   # set the email to the value
        p[email]++;   # count the occurance of "email"
      }

      # if we have more then 2 email occurances
      # print the line to f[email] and skip to the next line
      (p[email]>2) { print > f[email]; next }

      # if this is the first time we have email
      # store the full line in l[email]
      (p[email]==1){l[email]=$0}

      # if this is the second time we find email
      (p[email]==2){
         # create filename
         f[email]=email".txt";sub(/@/,"_at_",f[email]);
         # print first line to f[email]
         print l[email]>f[email];
         # print current line to f[email]
         print > f[email]
      }' *.csv

这样做的是每当它找到单词&#34; E-MAIL&#34;时,它会搜索出现该单词的字段编号,读取下一行并检索email地址。

然后它做了一些逻辑,它跟踪email发生了多少次。

  • 如果是第一次,它会将该行存储在l[email]
  • 如果是第二行,则会创建一个类似f[email]的文件名"foo_at_bar.com.txt",打印该文件中的第一行l[email]和当前行。
  • 如果是第三次或更长时间,只需将该行打印到f[email]

这会创建所有文件。

相关问题