我有大量的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命令?
答案 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