
У меня возникли проблемы со скриптом, обрабатывающим файл .csv.
Информация о .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
Вот как следует разделять информацию: MsgID,Дата,Кому,Копия,СК,Тема,Текст,Статус,Временная метка
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
Проблемы с основной частью возникают по двум причинам: «,» в тексте разрывается, когда я пытаюсь запустить скрипт, а другая причина — разрывы строк в тексте.
Вот сценарий, который я делал:
#!/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
решение1
Оболочка — это простоочень плохой инструмент для анализа текста. Его следует использовать только для самых простых задач, и, возможно, даже не тогда. Он медленный, неэффективный, его очень сложный синтаксис делает его подверженным ошибкам, и в нем отсутствуют самые основные инструменты обработки текста. Вдобавок ко всему, CSV — это сложный формат, который допускает вложенные и многострочные записи. Попытка разобрать CSV-файл в оболочке просто напрашивается на неприятности.
Поэтому вместо этого используйте правильный язык программирования с поддержкой парсинга CSV. Например, в 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))
Я сохранил скрипт выше как foo.py
и затем:
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
Как вы видите, он правильно распознал все поля. Так что, чтобы также отправить почту, вы можете сделать что-то вроде этого (адаптировано отсюда):
#!/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)
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Судя по имеющимся у вас опциям, вы, похоже, используете BSD mail
. У меня нет доступа к рабочей системе с установленным этим инструментом, поэтому я не смог протестировать скрипт отправки почты выше. Хотя это должно послужить по крайней мере хорошим началом.
решение2
Вы можете использовать такой инструмент, как Миллер (https://github.com/johnkerl/miller), специализирующийся на работе со структурированными текстовыми данными.
В примере, начиная с этого input.txt
файла
#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
и бег
mlr --implicit-csv-header --c2x cat then label MsgID,Date,To,CC,BCC,Subject,Body,Status,Timestamp input.txt
у тебя будет
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
Если вы хотите удалить возврат каретки в поле body, вы можете выполнить команду
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
иметь
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