2009-05-15 7 views
5

ich eine große Anzahl von CSV-Dateien, die unten wie folgt aussehen:vim & CSV-Datei: put Header Informationen in eine neue Spalte


xxxxxxxx
xxxxx
Versand, YD564n
xxxxxxxxx
xxxxx

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


Ich muss sie wie folgt aussehen:


xxxxxxxx
xxxxx
Versand, YD564n
xxxxxxxxx
xxxxx

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


YD564n ist eine Sendungsnummer und wird für jede CSV-Datei unterschiedlich sein. Aber es kommt immer direkt nach "Versand".

Welche Vim-Befehle kann ich verwenden?

Antwort

3

Sie können dies mit einem Makro tun und es über mehrere Dateien anwenden.

Hier ist ein Beispiel. Geben Sie Folgendes ein:

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

Nun, das sieht schrecklich aus. Lass mich sehen, ob ich das ein bisschen besser erklären kann.

3gg$: Zum Ende der dritten Zeile gehen.

"ayiw: Kopieren Sie das letzte Wort in das Register a.

:6,$s/^/<C-R>a/<CR>: In jeder Zeile ab dem 6. ersetzen Sie am Anfang, was auch immer in Register a ist.

:w<CR>:bn<CR>: Speichern und zum nächsten Puffer gehen.

Jetzt können Sie diese auf einen Schlüssel zuordnen, von

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

Dann, wenn Sie 200 csv-Dateien sagen, Sie öffnen vim als

vim *.csv 

und dann

200<C-A> 

Wo Sie dort Strg-A eingeben, sollte alles erledigt sein.

Das gesagt, ich wäre definitiv wohler dabei, dies in einer geeigneten Skriptsprache zu tun, es wäre viel einfacher.

4

In einem Dateityp nach dem im normalen Modus:

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

Beachten Sie, dass <CR> der Schlüssel ist, ENTER und <C-R> ist STRG + R.

Dies wird diese Datei aktualisieren und die Befehle in Register q wiederholen.

Dann in jedem anderen Dateityp @q (auch im normalen Modus). (Dies wird Register q Wiedergabe)

2

Dies als Perl Einzeiler getan werden könnte:

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

Dies wird die Sendungs-ID in $n lesen Inhalt shipment.csv in $c, extrahieren und prepend jede CSV Linie mit der Sendungsnummer. Die Datei wird an Ort und Stelle mit einer Sicherung geändert, die unter shipment.csv.bak gespeichert ist.

Um dies zu tun, von innen Vim, passen sie als Filter:

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

Nun, lass mich nicht heftig schlagen, aber ... Sie sollten sich überlegen: Sie dies in vim nicht !!

Dies ist ein klassisches Anwendungsbeispiel für Skriptsprachen. Nehmen Sie eine grundlegende Python, Perl oder Ruby Tutorial. Die Lösung dafür wäre drin.

Die Regex für diese möglicherweise nicht zu schwer und es ist machbar in vim. Aber es gibt viel einfachere Alternativen da draußen. Und viel flexiblere.

1

Warum vim?

dieses Shell-Skript Versuchen:

#!/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 

Sie durch bestimmte Dateien laufen könnte:

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

Ich denke auch, das für vim nicht gut geeignet ist, wie etwa in Bash statt?

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