这是我要修改的数据的示例:
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