5

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


xxxxxxxx
xxxxx
发货,YD564n
xxxxxxxx
xxxxx

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


我需要让它们看起来像下面这样:


xxxxxxxx
xxxxx
发货,YD564n
xxxxxxxx
xxxxx

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


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

我可以使用哪些 vim 命令?

4

6 回答 6

4

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

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

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

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

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

于 2009-05-15T07:26:20.130 回答
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 ,这一切都应该完成。

也就是说,我肯定会更舒服地用适当的脚本语言来做这件事,它会更直接。

于 2009-05-15T07:29:39.077 回答
2

这可以作为 Perl 单行来完成:

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

这将读取shipment.csvinto的内容$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'
于 2009-05-15T07:27:23.543 回答
1

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

这是脚本语言的经典用法示例。学习基本的 python、perl 或 ruby​​ 教程。解决方案就在其中。

正则表达式可能不会太难,并且在 vim 中是可行的。但是那里有更简单的选择。还有更灵活的。

于 2009-05-15T07:28:43.617 回答
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
于 2009-05-15T07:31:51.380 回答
1

我也认为这不太适合 vim,那么在 Bash 中呢?

FILENAME='filename.csv' && SHIPMENT=`grep Shipment $FILENAME | sed 's/^Shipment,//'` && cat $FILENAME | sed "s/^[0-9]/$SHIPMENT,&/" > $FILENAME
于 2009-05-15T07:32:55.137 回答