
.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
情報は次のように分割する必要があります。 メッセージID、日付、宛先、CC、BCC、件名、本文、ステータス、タイムスタンプ
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
私が抱えている問題は、本文部分に関するもので、その理由は 2 つあります。1 つは、スクリプトを実行しようとするとテキスト内の「,」が壊れてしまうこと、もう 1 つは、テキスト内で改行が起こってしまうことです。
私が実行していたスクリプトは次のとおりです。
#!/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 ファイルを解析しようとすると、トラブルを招くだけです。
したがって、代わりに 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
本文フィールドの改行を削除したい場合は、以下を実行します。
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