このようなファイルがあります。
103710:v2HAbAFH029324:[email protected]:localhost:Sent
103821:CCFE5609E3:[email protected]:localhost:bounced
103922:DFF19609E2:[email protected]:localhost:Deferred
私はそれに変更する必要があります。
{"randomId":{"s":"103710"},"id":{"s":"v2HAbAFH029324"},"userId":{"s":"[email protected]"},"dns":{"s":"localhost"},"status":{"s":"Sent"}}
{"randomId":{"s":"103821"},"id":{"s":"CCFE5609E3"},"userId":{"s":"[email protected]"},"dns":{"s":"localhost"},"status":{"s":"bounced"}}
{"randomId":{"s":"103922"},"id":{"s":"DFF19609E2"},"userId":{"s":"[email protected]"},"dns":{"s":"localhost"},"status":{"s":"Deferred"}}
このコードが欲しい
while read line
do
sed -i 's/^/{"randomId":{"s":"/' test
echo $line
echo $line | grep -q ":"
[ $? -eq 0 ] && echo "/"{"id":{"s":/"
[ $? -eq 1 ] && echo "/",{"userId":{"s":/"
[ $? -eq 2 ] && echo "/",{"host":{"s":/"
[ $? -eq 3 ] && echo "/",{"status":{"s":/"
echo "$line | " ";
done < test
最初の発生:add {"id":{"s":
、2番目の発生add{"userId":{"s":
答え1
grep/echo ブロックは有用な機能を実行しません。 $?一度だけ設定すると、フィールド全体が繰り返されません。
ありがたいことに、これを行うより簡単な方法があるようです。フィールドを変数に分割します。幸いなことにread
、次のことが可能です。
while IFS=':' read -r randomid id userid dns status; do
printf '{"randomId":{"s":"%s"},"id":{"s":"%s"},"userId":{"s":"%s"},"dns":{"s":"%s"},"status":{"s":"%s"}}\n' \
"$randomid" "$id" "$userid" "$dns" "$status"
done
printf
代わりに、よりおなじみのものを使用すると、必要なecho
シーケンス\"
をすべて回避できます。echo
行の末尾にバックスラッシュを使用して区切ります。
注:生成する形式はJSONと呼ばれ、それを生成するのに役立つツールがあるかもしれません(例:ジャック)。また、フィールドに二重引用符を含めることができる場合は、独自のエスケープが必要になる場合があります。
答え2
そしてperl
:
perl -MJSON -F: -ple '@A = qw/randomId id userId dns status/; $_ = encode_json({map { shift @A => { "s" => $_ } } @F } )' input.csv
答え3
データが区別されて読みやすいので、これを行う方法はいくつかあります。 Sedはデータを解析し、変更を1行で出力できます。
sed -r -i 's/^(.*):(.*):(.*):(.*):(.*)$/{"randomId":{"s":"\1"},"id":{"s":"\2"},"userId":{"s":"\3"},"dns":{"s":"\4"},"status":{"s":"\5"}}/' input.txt
キャプチャグループを使用すると、ファイルの始まり、区切り文字、ファイルの終わりの間のすべての内容をキャプチャし、そのグループの周囲のテキストのみを操作できます。各キャプチャグループは「\#」と呼ばれます。ここで、#はキャプチャグループの番号で、1から始まり、各グループに対して1ずつ増加します。
すでに述べたように、独自の区切り文字を設定することもできます。 BashにはIFS(Internal Field Separator)という組み込み変数があります。 IFS のデフォルト値は空白ですが、変更できます。 bashの例はすでに提供されており、コピーだけであるため、表示しません。
答え4
perl -F: -pale '
@A = qw/randomId id userId dns status/;
($k, $_) = (0, "{" . join(",", map qq/"$A[$k++]":{"s":"$_"}/, @F) . "}");
' yourfile
説明する
@F
分割されたフィールドを維持:
し、配列{"s":"fieldI"}
の対応する要素の前に接頭辞が付いた適切なマッサージを使用して一緒に接続します@A
。これらの要素はjoin
すべて on にまとめて,
「{"..."}」で囲みます。これで終わりました。