Vim和CSV文件: 将标题信息放入新列

5
我有很多类似以下的csv文件:

xxxxxxxx
xxxxx
Shipment,YD564n
xxxxxxxxx
xxxxx

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


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

xxxxxxxx
xxxxx
Shipment,YD564n
xxxxxxxxx
xxxxx

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


YD564n是一个装运号,对于每个csv文件都不同。但它总是在“Shipment,”之后出现。
我可以使用哪些vim命令?
6个回答

4

在正常模式下,输入以下内容:

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

请注意,<CR>是回车键,而<C-R>是CTRL-R。
这将更新该文件并在寄存器q中记录命令。
然后在每个其他文件中输入@q(也在普通模式下)。 (这将播放寄存器q)

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
这可以用Perl的一行命令来完成:
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'

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

1
我认为这并不适合在vim中完成,那么在Bash中怎么样?
FILENAME='filename.csv' && SHIPMENT=`grep Shipment $FILENAME | sed 's/^Shipment,//'` && cat $FILENAME | sed "s/^[0-9]/$SHIPMENT,&/" > $FILENAME

1

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

这是脚本语言的经典用例。 学习基础的Python、Perl或Ruby教程,其中就会有解决方案。

这个正则表达式可能并不太难,而且在vim中也是可行的。 但是还有更简单、更灵活的替代方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接