重组 csv 文件

重组 csv 文件

这是我要修改的数据的示例:

John,,
bim,bam,boom
tim,tam,toom
lam,loom,lim
Mary,,
pam,pim,poom
dam,dim,doom*

我尝试实现这一目标:

John,bim,bam,boom
John,tim,tam,toom
John,lam,loom,lim
Mary,pam,pim,poom
Mary,dam,dim,doom

当一个名字单独出现在一行时,它将成为下面所有行的一个新列,直到出现具有相同模式的下一个名字。

我想知道 awk 或其他工具是否可以提供帮助,但我有点迷失了。

我尝试设定一个条件(如果第 2 列和第 3 列为空,则执行某些操作),但现在对我来说看起来有点复杂。

答案1

你的想法是正确的:

我尝试设定一个条件(如果第2列和第3列为空,则执行某些操作)

具体来说,

  • 如果第 2 列和第 3 列为空,则保存第 1 列的值并继续
  • 否则,将保存的值添加到该行并打印它(有几种awk方法可以做到这一点)

例如

awk -F, '$2=="" && $3=="" {pfx=$1; next} {print pfx "," $0}' file.csv

或者更惯用地使用FS字段分隔符变量

awk -F, '$2=="" && $3=="" {pfx=$1; next} {$0 = pfx FS $0; print}' file.csv

或(因为默认操作 - 当规则评估为真时或1- 是打印记录)

awk -F, '$2=="" && $3=="" {pfx=$1; next} {$0 = pfx FS $0} 1' file.csv
John,bim,bam,boom
John,tim,tam,toom
John,lam,loom,lim
Mary,pam,pim,poom
Mary,dam,dim,doom

答案2

Perl 替代方案:

$ perl -F',' -lane 'if(@F == 1){$prefix = sprintf("%s,",@F);next;};print $prefix . $_' input.csv
John,bim,bam,boom
John,tim,tam,toom
John,lam,loom,lim
Mary,pam,pim,poom
Mary,dam,dim,doom

此操作的前提是,使用 as 运算符将每一行拆分为元素数组,,如果该数组中只有一个项目,我们使用该行作为前缀并转到下一行。长度超过 1 个元素的其他行将附加前缀。当然,当且仅当数组长度为 1 时前缀才会改变。

shift或者更短,按照 Glenn Jackman 的建议使用:

$ perl -F',' -lane 'if(@F == 1){$prefix = shift @F;next;};print $prefix . "," . $_' input.csv       

或者

$ perl -F, -lane '$,=","; if (1 == @F) {$name = shift @F} else {print $name, @F}' input.csv

相关内容