簡體   English   中英

檢查字符串是否存在於多個csv文件中並將行寫入文件

[英]Check if string exists in multiple csv files and write row to file

我得到了這個項目,我想檢查兩個或多個csv文件中是否存在電子郵件地址。 文件的數量可以有所不同,它們的前綴也可以不同,但​​是它們將始終存儲在同一目錄中。

我需要以下幫助

  1. 在兩個或多個文件中查找匹配項的方法。
  2. 一次搜索整個目錄
  3. 將匹配地址存在的所有行寫入新文件。
  4. 向我指出可以在腳本中使用的方向,在腳本中可以將其與“ if”語句一起使用,並與webb應用程序一起使用。

我看了看

根據特定關鍵字從CSV文件中提取行

但這需要我知道我要查找的電子郵件地址,而我不需要。

對於時間充裕的人,在下面的文章中,您可以找到到目前為止我“實現”的內容以及原始文件和所需輸出的示例。

將被檢查的原始文件的示例。 行數可以變化。 有時也可以在第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。

如果我沒有提供任何重要信息,拼寫錯誤或以錯誤的方式提出這個問題,我深表歉意。

很感謝任何形式的幫助!

要獲取目錄中所有文件的列表:

import os
file list = os.listdir()

您需要打開列表中的所有文件,並將所有電子郵件地址都放入字典中。 像這樣:

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

這將為您提供一個郵件地址出現頻率的計數。 然后,您可以將所有出現多次的所有地址寫入外出文件。

這可以在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開頭的行。

以下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

它的作用是每次找到單詞“ E-MAIL”,就會搜索出現該單詞的字段編號,讀取下一行並獲取email地址。

然后,它執行一些邏輯,跟蹤email發生的次數。

  • 如果是第一次,則將行存儲在l[email]
  • 如果是第二行,它將創建一個類似於"foo_at_bar.com.txt"的文件名f[email] ,並在該文件中輸出第一行l[email] ,並輸出當前行。
  • 如果是第三次或更長時間,則僅將行打印到f[email]

這將創建您所有文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM