
Tengo algunos problemas con un script que analiza un archivo .csv
Información sobre .csv:
#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
Así es como se debe dividir la información: ID de mensaje, fecha, para, CC, CCO, asunto, cuerpo, estado, marca de tiempo
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
Los problemas que tengo son con la parte del cuerpo por dos razones, el "," en el texto que se rompe cuando intento ejecutar el script y la otra razón son los saltos de línea en el texto.
Este es el guión que estaba haciendo:
#!/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
Respuesta1
El caparazón es sólo unMuy mala herramienta para analizar texto.. Sólo deberías usarlo para las tareas más simples, y probablemente ni siquiera entonces. Es lento, ineficiente, su sintaxis muy complicada lo hace propenso a errores y carece de las herramientas de procesamiento de texto más básicas. Además de esto, CSV es un formato complejo que permite entradas anidadas y de varias líneas. Intentar analizar un archivo CSV en el shell solo es buscar problemas.
Por lo tanto, utilice un lenguaje de programación adecuado que admita el análisis CSV. Por ejemplo, en Python:
#!/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))
Guardé el script anterior como foo.py
y luego:
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
Como puedes ver, ha reconocido correctamente todos los campos. Entonces, para enviar también el correo, puedes hacer algo como esto (adaptado de aquí):
#!/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)
DESCARGO DE RESPONSABILIDAD: Parece que estás usando BSD mail
según las opciones que tienes. No tengo acceso a un sistema que funcione con esa herramienta instalada, por lo que no pude probar el script de envío de correo anterior. Al menos debería servir como un buen comienzo.
Respuesta2
Podrías usar una herramienta como Miller (https://github.com/johnkerl/miller), especializado en trabajar con datos de texto estructurado.
En un ejemplo a partir de este input.txt
archivo
#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
y corriendo
mlr --implicit-csv-header --c2x cat then label MsgID,Date,To,CC,BCC,Subject,Body,Status,Timestamp input.txt
usted tendrá
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
Si desea eliminar el retorno de carro en el campo del cuerpo, puede ejecutar
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
tener
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