2016-06-29 10 views
1
Datei

Ich habe eine Datei mit Zahlen wieVIM Polsterung mit entsprechender Anzahl von“0" erhalten CSV

1, 2, 3 
4, 5 
6, 7, 8, 9,10,11 
12,13,14,15,16 
... 

ich durch Klotzen jede Zeile eine solche CSV-Datei erstellt werden soll, dass es 6 Werte getrennt durch 5 Kommas, also muss ich zu jeder Zeile eine entsprechende Anzahl von ", 0" hinzufügen. Es soll aussehen wie

1, 2, 3, 0, 0, 0 
4, 5, 0, 0, 0, 0 
6, 7, 8, 9,10,11 
12,13,14,15,16, 0 
... 

Wie würde ich das mit VIM tun?

Kann ich die Anzahl von "," in einer Zeile mit regulären Ausdrücken zählen und die richtige Anzahl von ", 0" zu jeder Zeile mit dem Ersatzbefehl s hinzufügen?

+0

Es ist möglich, Regex zu verwenden und die Anzahl der Kommas zu finden und dann eine ausdr an Ersatzteil verwenden, so etwas wie/\ = ausdr()Aber es gibt mehrere Möglichkeiten einfacher als Regex wie Makros oder Befehle. Nutzen Sie den Vorteil von vim. – SibiCoder

Antwort

3

Sie können zuerst sechs Nullen in allen Zeilen hinzufügen, unabhängig davon, wie viele Nummern sie haben, und dann können Sie alles in jeder Zeile vom sechsten Komma bis zum Ende löschen.

sie einzufügen,

 :1,$ normal! i,0,0,0,0,0,0 

vom sechsten Komma bis Ende zu löschen,

 :1,$normal! ^6f,D 

    ^moves to first character in line(which is obviously a number here) 

     6f, finds comma six times 

     D delete from cursor to end of line 

Beispiel:

Original-

   1,2, 
      3,6,7,0,0,0 
      4,5,6 
      11,12,13 

Nach sechs Nullen Hinzufügen

   1,2,0,0,0,0,0,0 
      3,6,7,0,0,0,0,0,0,0,0,0 
      4,5,6,0,0,0,0,0,0 
      11,12,13,0,0,0,0,0,0 

Nach sechs Komma Entfernen der Leitung erreichen

   1,2,0,0,0,0,0 
      3,6,7,0,0,0,0 
      4,5,6,0,0,0,0 
      11,12,13,0,0,0 
+0

Sie können ausgewählte Zeilennummern oder Marken anstelle von '1, $' verwenden. Dies ist ein einfacherer Ansatz als die Verwendung komplexer Regex. – SibiCoder

+0

Als eine Schussform von 'normal' können Sie' norm' verwenden – SibiCoder

5

Sie können zu beenden, die durch diesen Befehl eingeben:

:g/^/ s/^.*$/&,0,0,0,0,0,0/ | normal! 6f,D 
2

Mit perl:

perl -lpe '$_ .= ",0" x (5 - tr/,//)' file.txt 

Mit awk:

awk -v FS=, -v OFS=, '{ for(i = NF+1; i <= 6; i++) $i = 0 } 1' file.txt 

Mit sed:

sed ':b /^\([^,]*,\)\{5\}/ b; { s/$/,0/; b b }' file.txt 
2

Soweit wie diese von innen Vim tun, können Sie auch externe Programme Rohr Text durch und es wird den Eingang mit dem Ausgang ersetzen. Dies ist eine einfache Möglichkeit, um Sortierung, Deduplizierung, Grep-basierte Filterung usw. oder einige der Vorschläge von Sato zu nutzen. Also, wenn Sie ein Skript namens standardize_commas.py haben, versuchen Sie, Ihren Block mit dem visuellen Linienmodus auszuwählen (shift + v, dann select), und tippen Sie dann etwas wie :! python /tmp/standardize_commas.py ein. Es sollte dieser Zeichenfolge ein wenig vorangestellt werden, um anzuzeigen, dass der Befehl auf den aktuell ausgewählten Zeilen ausgeführt wird.

FYI, das war mein /tmp/standardize_commas.py Skript:

import sys 

max_width = 0 
rows = [] 
for line in sys.stdin: 
    line = line.strip() 
    existing_vals = line.split(",") 
    rows.append(existing_vals) 
    max_width = max(max_width, len(existing_vals)) 

for row in rows: 
    zeros_needed = max_width - len(row) 
    full_values = row + ["0"] * zeros_needed 
    print ",".join(full_values)