vim& csv文件:将标题信息放入新列

时间:2009-05-15 07:04:44

标签: regex vim csv replace copy-paste

我有大量的csv文件,如下所示:


XXXXXXXX
XXXXX
出货,YD564n
XXXXXXXXX
xxxxx

1,RR1760
2,HI3503
3,HI4084
4,HI1824


我需要让它们看起来如下:


XXXXXXXX
XXXXX
出货,YD564n
XXXXXXXXX
xxxxx

YD564n,1,RR1760
YD564n,2,HI3503
YD564n,3,HI4084
YD564n,4,HI1824


YD564n是一个货件编号,每个csv文件都有所不同。但它总是在“装运”之后出现。

我可以使用哪些vim命令?

6 个答案:

答案 0 :(得分:4)

在一个文件中,在正常模式下键入以下内容:

qqgg/^Shipment,<CR>ww"ay$}j:.,$s/^/<C-R>a,<CR>q

请注意,<CR>是ENTER键,<C-R>是CTRL-R。

这将更新该文件并重新记录寄存器q中的命令。

然后在每个其他文件中键入@q(也在正常模式下)。 (这将播放寄存器q)

答案 1 :(得分:3)

您可以使用宏执行此操作,并将其应用于多个文件。

这是一个例子。按原样键入以下内容:

3gg$"ayiw:6,$s/^/<C-R>a/<CR>:w<CR>:bn<CR>

现在看起来很可怕。让我看看我是否可以更好地解释一下。

3gg$:转到第三行的末尾。

"ayiw:将最后一个字复制到注册表a

:6,$s/^/<C-R>a/<CR>:在从第6开始的每一行中,在开头替换寄存器a中的任何内容。

:w<CR>:bn<CR>:保存并转到下一个缓冲区。

现在您可以通过

将其映射到一个键
:nnoremap <C-A> 3gg$"ayiw:6,$s/^/<C-R>a/<CR>:w<CR>:bn<CR>

然后,如果您说200个csv文件,则打开vim作为

vim *.csv

然后

200<C-A>

在那里键入Ctrl-A,应该全部完成。

那就是说,我用一种适当的脚本语言来做这件事肯定会更加舒服,它会更加直截了当。

答案 2 :(得分:2)

这可以作为Perl one-liner进行:

perl -i.bak -e' $c = do {local $/; <>};
                ($n) = ($c =~ /Shipment,(\w+)/);
                $c =~ s/^(\d+,)/$n,$1/gm;
                print $c' shipment.csv

这会将shipment.csv的内容读入$c,将货件ID提取到$n,并在每个CSV行前面加上货件编号。该文件将在保存到shipment.csv.bak的备份中就地修改。

要在Vim中执行此操作,请将其修改为过滤器:

:%!perl -e' $c = do {local $/; <>}; ($n) = ($c =~ /Shipment,(\w+)/); $c =~ s/^(\d+,)/$n,$1/gm; print $c'

答案 3 :(得分:1)

好吧,不要打击我,但是......你可以考虑:不要在vim中这样做!!

这是脚本语言的经典用法示例。 参加一个基本的python,perl或ruby教程。解决方案就是这样 在其中。

这方面的正则表达式可能不会太难,并且中可以在vim中使用。 但那里有更容易的替代品。 而且更加灵活。

答案 4 :(得分:1)

为什么选择vim?

试试这个shell脚本:

#!/bin/sh

input=$1

shipment=`grep Shipment $input|awk -F, '{print $2}'`

mv $input $input.orig

sed -e "s/^\([0-9]\)/$shipment,\1/" $input.orig > $input

您可以遍历特定文件:

for input in *.txt
do
    script.sh $i
done

答案 5 :(得分:1)

我也认为这不适合vim,而是在Bash中怎么样?

FILENAME='filename.csv' && SHIPMENT=`grep Shipment $FILENAME | sed 's/^Shipment,//'` && cat $FILENAME | sed "s/^[0-9]/$SHIPMENT,&/" > $FILENAME