Extrahieren Sie Informationen zwischen Anführungszeichen aus der CSV-Datei

Extrahieren Sie Informationen zwischen Anführungszeichen aus der CSV-Datei

Ich habe Probleme mit einem Skript, das eine CSV-Datei analysiert

Informationen zur CSV-Datei:

#1,13/8/2020,[email protected],[email protected],,Subject,"Dear Dude,

Information have been updated. Please login to APP to review by 30th August 2020. Thank you.

Best regards,
Mr. Mack",Pending,13/8/2020 12:35

So sollten Informationen aufgeteilt werden: MsgID,Datum,An,CC,BCC,Betreff,Text,Status,Zeitstempel

MsgID=#1
Date=13/8/2020
[email protected]
[email protected]
BCC=
Subject=Subject
Body=Dear Dude,
Information have been updated. Please login to APP to review by 30th August 2020. Thank you.
Best regards,
Mr. Mack
Status=Pending
Timestamp=13/8/2020 12:35

Ich habe aus zwei Gründen Probleme mit dem Hauptteil: Das „,“ im Text, das umbricht, wenn ich versuche, das Skript auszuführen, und der andere Grund sind die Zeilenumbrüche im Text.

Dies ist das Skript, das ich erstellt habe:

#!/bin/bash

export TIMESTAMP="$( date '+%d/%m/%Y %H:%M:%S' )"
INPUT=/tmp/test.csv
OUTPUT=/tmp/test.csv.out
OLDIFS=$IFS
IFS=','
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read msgid dat to cc bcc subject body status timesta
do
        echo "MSG ID : $msgid" 
        echo "Date : $dat"
        echo "To : $to"
        echo "CC : $cc"
        echo "BCC : $bcc"
        echo "Subject : $subject"
        echo "Body : $body"
        echo "Status : $status"
        echo "Timestamp : $timesta"
echo $body | mail -s "$subject" $to -c $cc -b $bcc
printf "$msgid,$dat,$to,$cc,$bcc,$subject,$body,Sent,$TIMESTAMP" >> $OUTPUT
done < $INPUT
IFS=$OLDIFS

Antwort1

Die Schale ist nur einsehr schlechtes Tool zum Textparsing. Sie sollten es nur für die einfachsten Aufgaben verwenden und wahrscheinlich nicht einmal dann. Es ist langsam, ineffizient, seine sehr komplizierte Syntax macht es fehleranfällig und es fehlen die grundlegendsten Textverarbeitungstools. Darüber hinaus ist CSV ein komplexes Format, das verschachtelte und mehrzeilige Einträge zulässt. Der Versuch, eine CSV-Datei in der Shell zu analysieren, ist einfach nur ein Ärgernis.

Verwenden Sie stattdessen eine geeignete Programmiersprache mit Unterstützung für CSV-Parsing. In Python beispielsweise:

#!/bin/python3
import csv
import sys

with open(sys.argv[1], newline='') as csvfile:
    fieldnames = ("MsgID","Date","To","CC","BCC",
                  "Subject","Body","Status","Timestamp")
    reader = csv.reader(csvfile, delimiter=',',
    for row in reader:
        for fieldName, value in zip(fieldnames,row):
            print("%s: %s" % (fieldName,value))

Ich habe das obige Skript wie folgt gespeichert foo.pyund dann:

MsgID: #1
Date: 13/8/2020
To: [email protected]
CC: [email protected]
BCC: 
Subject: Subject
Body: Dear Dude,

Information have been updated. Please login to APP to review by 30th August 2020. Thank you.

Best regards,
Mr. Mack
Status: Pending
Timestamp: 13/8/2020 12:35

Wie Sie sehen, wurden alle Felder korrekt erkannt. Um die E-Mail auch zu versenden, können Sie Folgendes tun (angepasst von hier):

#!/bin/python3
import csv
import sys
import subprocess
import os

def send_message(to, cc, bcc, subject, body):
    try:
        process = subprocess.Popen(['mail', '-s', subject, '-c', cc, '-b', bcc, to],
                                   stdin=subprocess.PIPE)
    except Exception as error:
      print(error)
    process.communicate(body)


with open(sys.argv[1], newline='') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    for row in reader:
        (msgID, date, to, cc, bcc, subj, body, status, timestamp) = row
        send_message(to, cc, bcc, subj, body)

HAFTUNGSAUSSCHLUSS: Den Optionen nach, die Sie haben, scheinen Sie BSD zu verwenden mail. Ich habe keinen Zugriff auf ein funktionierendes System mit diesem installierten Tool, daher konnte ich das obige Skript zum Senden von E-Mails nicht testen. Es sollte jedoch zumindest als guter Anfang dienen.

Antwort2

Sie könnten ein Werkzeug wie Miller verwenden (https://github.com/johnkerl/miller), spezialisiert auf die Arbeit mit strukturierten Textdaten.

Im Beispiel ausgehend von dieser input.txtDatei

#1,13/8/2020,[email protected],[email protected],,Subject,"Dear Dude,

Information have been updated. Please login to APP to review by 30th August 2020. Thank you.

Best regards,
Mr. Mack",Pending,13/8/2020 12:35

und läuft

mlr --implicit-csv-header --c2x cat then label MsgID,Date,To,CC,BCC,Subject,Body,Status,Timestamp input.txt

du wirst haben

MsgID     #1
Date      13/8/2020
To        [email protected]
CC        [email protected]
BCC
Subject   Subject
Body      Dear Dude,

Information have been updated. Please login to APP to review by 30th August 2020. Thank you.

Best regards,
Mr. Mack
Status    Pending
Timestamp 13/8/2020 12:35

Wenn Sie den Wagenrücklauf im Textfeld entfernen möchten, können Sie Folgendes ausführen:

mlr --implicit-csv-header --c2x cat then label MsgID,Date,To,CC,BCC,Subject,Body,Status,Timestamp then put '$Body=gsub($Body,"\n"," ")' input.txt

haben

MsgID     #1
Date      13/8/2020
To        [email protected]
CC        [email protected]
BCC
Subject   Subject
Body      Dear Dude,  Information have been updated. Please login to APP to review by 30th August 2020. Thank you.  Best regards, Mr. Mack
Status    Pending
Timestamp 13/8/2020 12:35

verwandte Informationen