2

我有一个看起来像这样的 CSV 文件:

productSku-1,attribute1,2,3
productSku-1,attribute4,5
productSku-1,attribute4,5
productSku-2,attribute1,2,3
productSku-2,attribute4,5
productSku-3,attribute1,1

我试图将相同的产品属性“折叠”成一行,同时去掉productSku. 因此,我将产品与下一行匹配,然后删除下一productSku行以及换行符以将其压缩为一行。在上面的示例中,结果应如下所示:

productSku1,attribute1,2,3,attribute4,5,attribute4,5
productSku2,attribute1,2,3,attribute4,5
productSku3,attribute1,1

我认为以下替换命令会起作用,但我从未使用过该\% 符号。

:%s/(^[A-Za-z0-9-]+)(.)((\%(\n\1)(.))+)/\1\2\3

我认为它会从匹配中排除匹配 \3......但它不起作用。

4

2 回答 2

1

解决这个问题的一种方法是这样的:

:sort
qqjkdt,:g/<C-r>"/norm dt,-gJ<Enter>0P+q
10000@q

一步步

:sort- 按 productSku 对所有行进行排序

qq- 开始录音,见:help qq

jk- 这是一个小宏黑客......如果我们到达最后一行,它将抛出一个错误,并且命令的其余部分将不会执行。

dt,- 删除productSku

:g/- 启动:global命令,见:help :global

<C-r>"- 插入"寄存器的内容(我们删除的productSku)

norm- 短缺:help :normal

dt,- 删除 productSku,因为我们不想要它们

-- 转到上一行

gJ- 加入没有任何空格的行

<Enter>- 完成:global命令

0P- 将 productSku 放回行首

+- 下移一行

q- 完成录音

10000@q重复录音 10k 次(或更多,如果你需要)

于 2012-08-11T05:07:40.943 回答
1

我会使用以下有效的命令。

:g/\%(^\1,.*\n\)\@<=\([^,]*\)/s/$/,/|-j!
于 2012-08-12T12:04:57.443 回答