我有一个CSV文件,在此CSV中,列中缺少一些条目。如果未设置列,我想添加空值。
以下是CSV文件的结构:
ID; LON; LAT;图像;历史;地址;文本;类型;名称;网络; DATE_OF_BIRTH; date_of_death;起始日期
完整的数据行如下所示:
n3329319394; 4.369872; 50.866430;历史=纪念馆;图像=文件:Schaerbeek_40_rue_Vondel_Les_pavés_de_la_mémoire.jpg;纪念:ADDR = 40, Rue Vondel - Vondelstraat,Schaerbeek;纪念馆:text = Ici habitait Elisabeth Orcher-KarolinskiNée1912resistanterrêtée15.8.1942 interneeMalinesdéportée18.8.1942Auschwitzassassinée 20.8.1942; memorial:type = stolperstein; name = Elisabeth Orcher-Karolinski; network = Stolpersteine 布鲁塞尔;人:DATE_OF_BIRTH = 1912-00-00;人:date_of_death = 1942年8月20日
但有时数据行看起来像这样:
n4208925477; 5.041860; 52.141352;历史=纪念馆;纪念:ADDR = Langegracht 27;纪念:type = stolperstein; name = Lucas& Clara IJzerman
知道如何轻松转换这些数据吗?一个好的提示可能是限定词:“image = ...”等。
谢谢, 比约恩
答案 0 :(得分:0)
[投诉]
[投诉]
但你提出了我的好奇心。因此,我试图解决它。 (特别是,在你的样本数据中提到Stolperstein
- 非常聪明。现在,我感觉像是一个“帮助好人”的使命......)
我简化了你的问题:
我认为字段id
,lon
和lat
是强制性的。
我考虑了可选的命名字段name
,historic
和image
。
我的测试数据test-complete-lines.txt
:
n3329319394;4.369872;50.866430;name=Klaus Mustermann;historic=memorial;image=j.doe-de.png
n3329319395;4.369872;50.866430;name=Gabi Mustermann
n4208925477;5.041860;52.141352;historic=memorial
n4208925477;5.041860;52.141352;image=the-image.png
n3329319395;4.369872;50.866430;name=Gabi Mustermann;historic=memorial
n3329319395;4.369872;50.866430;name=Gabi Mustermann;image=j.doe.female-de.png
我的脚本test-complete-lines.awk
:
BEGIN { FS=";" }
# get mandatory fields id, lon, lat
{ id = $1 ; lon = $2 ; lat = $3 }
# set optional fields empty
{ name=";name=" ; historic=";historic=" ; image=";image=" }
# replace found fields with values
/;name=/ { name = gensub(/^.*(;name=[^;]*).*$/, "\\1", "g", $0) }
/;historic=/ { historic = gensub(/^.*(;historic=[^;]*).*$/, "\\1", "g", $0) }
/;image=/ { image = gensub(/^.*(;image=[^;]*).*$/, "\\1", "g", $0) }
# print processed line
{ print id";"lon";"lat""name""historic""image }
使用gawk进行测试(bash,cygwin,Windows 10(64位)):
$ awk --version
GNU Awk 4.1.4, API: 1.1 (GNU MPFR 3.1.5-p10, GNU MP 6.1.2)
Copyright (C) 1989, 1991-2016 Free Software Foundation.
$ awk -f test-complete-lines.awk <test-complete-lines.txt
n3329319394;4.369872;50.866430;name=Klaus Mustermann;historic=memorial;image=j.doe-de.png
n3329319395;4.369872;50.866430;name=Gabi Mustermann;historic=;image=
n4208925477;5.041860;52.141352;name=;historic=memorial;image=
n4208925477;5.041860;52.141352;name=;historic=;image=the-image.png
n3329319395;4.369872;50.866430;name=Gabi Mustermann;historic=memorial;image=
n3329319395;4.369872;50.866430;name=Gabi Mustermann;historic=;image=j.doe.female-de.png
$
注意:
替换找到的字段假定内容中不会显示;
。我建议你制作一个计数器样本(内容中出现;
)。这可能会激活某种引用或转义。因此,可能需要额外处理此类案件。
我只提到了一些指定的字段。您必须按照该方案添加其余部分。
顺便说一下。我在示例文本中意外地出了一个空行。这产生了:;;;name=;historic=;image=
如果有必要处理空行,可能会插入另一条规则(BEGIN { }
之后):
/^[ \t]*$/ { skip }
在我的第一个版本中,我的示例数据中有一个拼写错误 - 遗忘;
。因此,image=
成为name=
的内容,但也被认为是个别字段。假设命名字段可能不作为第一个字段出现,我将其修复为包括前面;
字段名称的模式。