Domanda

Ho un gran numero di file csv che assomigliano a questo qui sotto:


xxxxxxxx
xxxxx
La spedizione, YD564n
xxxxxxxxx
xxxxx

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


ho bisogno di farli apparire come il seguente:


xxxxxxxx
xxxxx
La spedizione, YD564n
xxxxxxxxx
xxxxx

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


YD564n è un numero di spedizione e sarà diverso per ogni file CSV. Ma si tratta sempre subito dopo "Spedizione".

Quale comando vim (s) posso utilizzare?

È stato utile?

Soluzione

È possibile farlo utilizzando una macro, e la sua applicazione su più file.

Ecco un esempio. Digitare quanto segue come è:

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

Ora che sembra orrendo. Fammi vedere se riesco a spiegare che un po 'meglio.

3gg$:. Vai alla fine della terza riga

"ayiw:. Copiare l'ultima parola nel registro a

:6,$s/^/<C-R>a/<CR>:. In ogni linea dal 6 in poi, sostituire al principio tutto ciò che è in un registro

:w<CR>:bn<CR>:. Salvare e andare al buffer successivo

Ora è possibile associare questo ad un tasto, da

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

Quindi se avete dire 200 file csv, è aperta come vim

vim *.csv

e quindi

200<C-A>

Dove si digita Ctrl-A là, e dovrebbe essere tutto fatto.

Detto questo, mi piacerebbe sicuramente essere più comodo fare questo in un linguaggio di scripting corretta, sarebbe molto più semplice.

Altri suggerimenti

In un tipo di file seguente in modalità normale:

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

Si noti che <CR> è il tasto INVIO, e <C-R> è CTRL-R.

Ciò aggiornerà il file e recrd i comandi nel registro q.

Quindi in ogni altro tipo di file @q (anche in modalità normale). (Questo verrà riprodotto registro q)

Ciò potrebbe essere fatto come Perl one-liner:

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

Questa leggerà i contenuti del shipment.csv in $c, estrarre l'ID spedizione in $n, e anteporre ogni linea CSV con il numero di spedizione. Il file verrà modificato sul posto con un backup salvato shipment.csv.bak.

Per fare questo dall'interno di Vim, adattarlo come un filtro:

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

Beh, non mi bash, ma ... si potrebbe prendere in considerazione: Non fare questo in vim !!

Questo è un esempio di utilizzo classico per linguaggi di scripting. Prendete un Python, Perl o Ruby tutorial di base. La soluzione per questo sarebbe essere in esso.

L'espressione regolare per questo potrebbe non essere troppo difficile e è fattibile in vim. Ma ci sono alternative molto più facili là fuori. E quelli molto più flessibile.

Perché vim?

Prova questo script di 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

Si potrebbe scorrere file specifici:

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

Credo anche che questo non è adatto per vim, che ne dite di Bash, invece?

FILENAME='filename.csv' && SHIPMENT=`grep Shipment $FILENAME | sed 's/^Shipment,//'` && cat $FILENAME | sed "s/^[0-9]/$SHIPMENT,&/" > $FILENAME
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top