0

我有一个这种格式的 3Gb 文件:

...
201211 001093223359 "PLANO ESPECIAL" "PLANO NOVO"
201211 001199175239 "PLANO ESPECIAL" "PLANO NOVO"
201211 001292676219 "PLANO ESPECIAL" "PLANO NOVO"
...

我需要将其格式更改为如下所示:

...
201211;001093223359;"PLANO ESPECIAL";"PLANO NOVO"
201211;001199175239;"PLANO ESPECIAL";"PLANO NOVO"
201211;001292676219;"PLANO ESPECIAL";"PLANO NOVO"
...

前 5 行与输入文件中的完全相同:

"Mes_Referencia" "Num_Telefone" "Dsc_Plano_Tarifario" "Grupo Plano"
201211 2183223350 "INFINITY PR?" "PLANO INFINITY"
201211 2169175232 "INFINITY PR?" "PLANO INFINITY"
201211 2182676211 "INFINITY PR?" "PLANO INFINITY"
201211 2281699337 "INFINITY PR?" "PLANO INFINITY"
201211 2179173096 "INFINITY PR?" "PLANO INFINITY"

评论: ? 在“无限公关?” 是因为它是“É”(它是葡萄牙语 - 巴西)。

如何将分隔符“”(空格)更改为“;” 不改变最后两列字符串中的空格?

提前致谢!

4

5 回答 5

2

无论文件中有多少行,这都会起作用,因为它一次只处理一行:

awk 'BEGIN{FS=OFS="\""} {for (i=1;i<NF;i+=2) gsub(/ /,";",$i)} 1' file

例如:

$ cat file
"Mes_Referencia" "Num_Telefone" "Dsc_Plano_Tarifario" "Grupo Plano"
201211 2183223350 "INFINITY PR?" "PLANO INFINITY"
201211 2169175232 "INFINITY PR?" "PLANO INFINITY"
201211 2182676211 "INFINITY PR?" "PLANO INFINITY"
201211 2281699337 "INFINITY PR?" "PLANO INFINITY"
201211 2179173096 "INFINITY PR?" "PLANO INFINITY"
$
$ awk 'BEGIN{FS=OFS="\""} {for (i=1;i<NF;i+=2) gsub(/ /,";",$i)} 1' file
"Mes_Referencia";"Num_Telefone";"Dsc_Plano_Tarifario";"Grupo Plano"
201211;2183223350;"INFINITY PR?";"PLANO INFINITY"
201211;2169175232;"INFINITY PR?";"PLANO INFINITY"
201211;2182676211;"INFINITY PR?";"PLANO INFINITY"
201211;2281699337;"INFINITY PR?";"PLANO INFINITY"
201211;2179173096;"INFINITY PR?";"PLANO INFINITY"
于 2013-02-22T19:39:46.407 回答
2

通过以下命令过滤您的文件:

sed -E -e 's/ ([^ "]*|"[^"]*")/;\1/g'

此命令假定第一列没有被引用。如果可以,正则表达式会稍微复杂一些。

样本输入:

201211 2183223350 "INFINITY PRE" "PLANO INFINITY"
201211 2182067250 "ASS. PLANO NOSSO MODO-G11" "OUTROS"
201211 8199712912 "TIM LIBERTY CONTROLE" "PLANO LIBERTY"

样本输出:

201211;2183223350;"INFINITY PRE";"PLANO INFINITY"
201211;2182067250;"ASS. PLANO NOSSO MODO-G11";"OUTROS"
201211;8199712912;"TIM LIBERTY CONTROLE";"PLANO LIBERTY"
于 2013-02-22T18:59:27.063 回答
1

如何用;和每个" "替换前 2 个空格";"

$ sed 's/ /;/;s/ /;/;s/" "/";"/g' file
201211;001093223359;"PLANO ESPECIAL";"PLANO NOVO"
201211;001199175239;"PLANO ESPECIAL";"PLANO NOVO"
201211;001292676219;"PLANO ESPECIAL";"PLANO NOVO"

使用-i开关进行内联更改。

使用具有 30000003 行的文件的一些时间:

$ time sed 's/ /;/;s/ /;/;s/" "/";"/g' f1 > /dev/null

real    1m58.305s
user    1m54.811s
sys 0m1.488s

$ time awk 'BEGIN{FS=OFS="\""} {for (i=1;i<NF;i+=2) gsub(/ /,",",$i)} 1' f1 > /dev/null

real    1m46.916s
user    1m45.831s
sys 0m0.852s


$ time sed -E -e 's/ ([^ "]*|"[^"]*")/;\1/g' f1 > /dev/null

real    20m52.172s
user    20m47.430s
sys 0m2.536s

贪婪的运算符和反向引用的巨大惩罚!

于 2013-02-22T20:04:57.437 回答
0

尝试:

awk 'NR%2{gsub(/[ \t]+/,";")}1' RS=\" ORS=\" file
于 2013-02-22T20:46:52.127 回答
0

awk应该做的伎俩。

awk -v OFS=";" '{print $1,$2,$3" "$4,$5" "$6}'

于 2013-02-22T18:50:17.040 回答