我需要管理我公司的smtp日志文件处理。
这些日志文件需要导入到MSSQL中,因此我的工作就是提供这些数据。
我收到了奇怪的未送达消息“;”在字符串中,我需要用逗号替换它。
所以我得到了:
Sender;Recipient;Operation;Answer;Error;Servername
bla@bla.com;rockit@sohard.com;RCPT TO;450;+4.2.0+<rockit@sohard.com>:+Recipient+address+rejected:+Policy+restrictions;+try+later;M0641
提到“;”在“限制”之后的答案字段中,不知道为什么邮件服务器发送分号,也许是为了惹恼我:P
在我做了大量研究后,我尝试用awk跟进:
awk 'BEGIN{FS=OFS=";"} {for (i=5;i<=NF;i++) gsub (";",",",$i)} 1' myfile.csv
这个命令实际上有效,但似乎它对我的文件没有任何作用,“;”在错误字段中仍然存在。我在这里缺少什么?
答案 0 :(得分:2)
;
,
$ awk -F\; '{for (i=1;i<=NF;i++) printf "%s%s",$i,(i==NF?ORS:(i<=4?";":","))}' myfile.csv
Sender;Recipient;Operation;Answer;Error,Servername
bla@bla.com;rockit@sohard.com;RCPT TO;450;+4.2.0+<rockit@sohard.com>:+Recipient+address+rejected:+Policy+restrictions,+try+later,M0641
工作原理:
-F\;
这会将输入的字段分隔符设置为;
。
for (i=1;i<=NF;i++) printf "%s%s",$i,(i==NF?ORS:(i<=4?";":","))
这会遍历每个字段并打印字段,然后按(a)ORS(如果我们在最后一个字段上),或者(b),
如果是在字段5或更高字段,或(c){{ 1}}如果我们在前四个字段之一。
;
;
尝试:
,
工作原理:
$ awk -F\; '{$1=$1} 1' OFS=, myfile.csv
Sender,Recipient,Operation,Answer,Error,Servername
bla@bla.com,rockit@sohard.com,RCPT TO,450,+4.2.0+<rockit@sohard.com>:+Recipient+address+rejected:+Policy+restrictions,+try+later,M0641
这会将输入的字段分隔符设置为分号。
-F\;
这会导致awk认为该行已被更改,因此awk将更新输出行以使用新的字段分隔符。
$1=$1
这告诉awk打印该行。
1
这会将输出上的字段分隔符设置为逗号。
OFS=,
$ awk '{gsub(/;/, ",")} 1' myfile.csv
Sender,Recipient,Operation,Answer,Error,Servername
bla@bla.com,rockit@sohard.com,RCPT TO,450,+4.2.0+<rockit@sohard.com>:+Recipient+address+rejected:+Policy+restrictions,+try+later,M0641
答案 1 :(得分:1)
我认为你的问题是在五个字段范围的输入中替换逻辑第四个字段中的unquotes分隔符。虽然这个重复的脚本应该更容易理解
$ awk '{n=split($0,a,";");
for(i=1; i<4; i++) printf "%s;", a[i];
for(i=4; i<n-1; i++) printf "%s,", a[i];
printf "%s;%s\n", a[n-1], a[n]}' file
根据@Ed Morton的评论写一个更好的方法
$ awk -F';' '{for(i=1; i<NF-1; i++) printf "%s"(i<4?FS:","), $i;
print $(NF-1) FS $NF}' file
输入
1;2;3;4a;4b;4c;5
1;2;3;4;5
它会生成
1;2;3;4a,4b,4c;5
1;2;3;4;5
答案 2 :(得分:0)
如果违规的分号只出现在你的第5个字段中,那么你可以使用GNU awk为第3个arg匹配():
$ awk 'match($0,/(([^;]+;){4})(.*)(;[^;]+$)/,a){gsub(/;/,",",a[3]); print a[1] a[3] a[4]}' file
bla@bla.com;rockit@sohard.com;RCPT TO;450;+4.2.0+<rockit@sohard.com>:+Recipient+address+rejected:+Policy+restrictions,+try+later;M0641
答案 3 :(得分:0)
如果您的第五个;
应该被删除,请将$ 6追加到$ 5并相应提前。这可以通过for
循环完成(SO中有例子),但由于错误接近结尾,我们只是以更简单的方式做到这一点:
$ awk 'BEGIN {FS=OFS=";"} NR==1 {nf=NF} NF==(nf+1) {$5=$5 "," $6; $6=$7; NF=nf} 1' file
说明:
BEGIN {FS=OFS=";"} # set separator
NR==1 {nf=NF} # get field count from the first record (6)
NF==(nf+1) { # if record is one field longer:
$5=$5 "," $6 # append $6 to $5, comma-separated
$6=$7 # set $7 (NF) to $6 (nf)
NF=nf # reset NF
} 1 # output
测试:运行程序并将输出发送到cut -d\; -f 5
输出:
Error
+4.2.0+<rockit@sohard.com>:+Recipient+address+rejected:+Policy+restrictions,+try+later