2009-05-15 13 views
5

J'ai un grand nombre de fichiers csv qui ressemblent à ceci ci-dessous:vim & fichier csv: informations d'en-tête mis dans une nouvelle colonne


xxxxxxxx
xxxxx
Expédition, YD564n
xxxxxxxxx
xxxxx

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


je dois les faire ressembler à ce qui suit:


xxxxxxxx
xxxxx
Expédition, YD564n
xxxxxxxxx
xxxxx

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


YD564n est un numéro d'expédition et sera différent pour chaque fichier csv. Mais il vient toujours juste après "Expédition".

Quelle (s) commande (s) vim puis-je utiliser?

Répondre

3

Vous pouvez le faire en utilisant une macro et en l'appliquant sur plusieurs fichiers.

Voici un exemple. Tapez le texte suivant tel quel:

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

Maintenant, cela semble horrible. Laissez-moi voir si je peux expliquer un peu mieux.

3gg$: Aller à la fin de la troisième ligne.

"ayiw: Copiez le dernier mot dans le registre a.

:6,$s/^/<C-R>a/<CR>: Dans chaque ligne à partir du 6ème, remplacez au début ce qui est dans le registre a.

:w<CR>:bn<CR>: Enregistrer et passer au tampon suivant.

Maintenant, vous pouvez mapper ce à une clé, par

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

Alors si vous avez dit 200 fichiers csv, vous ouvrez vim comme

vim *.csv 

puis

200<C-A> 

Où vous tapez Ctrl-A, et tout devrait être fait. Cela dit, je serais certainement plus à l'aise de le faire dans un langage de script approprié, ce serait beaucoup plus simple.

4

Dans un type de fichier les suivantes en mode normal:

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

Notez que <CR> est la touche ENTER et <C-R> est CTRL-R.

Ceci mettra à jour ce fichier et recrèvera les commandes dans le registre q. Ensuite, dans chaque autre type de fichier @q (également en mode normal).

(Cela lire registre q)

2

Cela pourrait se faire en tant que Perl one-liner:

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

Cela lire le contenu de shipment.csv dans $c, extraire l'ID d'expédition dans $n et préfixer chaque CSV ligne avec le numéro d'expédition. Le fichier sera modifié sur place avec une sauvegarde enregistrée au shipment.csv.bak.

Pour ce faire, à partir de Vim, adaptez comme un filtre:

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

Eh bien, ne me bash pas, mais ... vous pourriez envisager: Ne pas faire cela dans vim !!

Ceci est un exemple d'utilisation classique pour les langages de script. Prenez un tutoriel de base sur python, perl ou ruby. La solution pour cela serait d'être dedans.

La regex pour cela peut ne pas être trop difficile et est faisable dans vim. Mais il existe des alternatives beaucoup plus faciles là-bas. Et beaucoup plus flexibles.

1

Pourquoi vim?

Essayez ce script 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 

Vous pouvez parcourir les fichiers spécifiques:

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

Je pense aussi que ce n'est pas bien adapté pour vim, que diriez-vous à la place Bash?

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