2013-04-18 7 views
5

diesen Fall vor: Ich habe einige Daten, die wie folgt aussieht:Format Data: Machen Sie Spalten in Zeilen (und umgekehrt)

1.9170000e + 03 $ 1.6909110e + 00
1.4550000e + 03 $ 1.7775459e + 00
1.1800000e + 03 $ 1.8771469e + 00
1.0000000e + 03 $ 1.9992190e + 00
8.7500000e + 02 $ 2.1938025e + 00
7.8300000e + 02 $ 2.5585915e + 00

Beachten Sie, dass das Dollarzeichen, das die zwei Spalten trennt, ein beliebiges Zeichen sein kann (von einer bestimmten Anzahl von Leerzeichen, dem Zeichen \ t (Tab), einem Komma oder nur einem beliebigen Zeichen, das zum Trennen der Spalte verwendet wird). Beachten Sie außerdem, dass die Daten möglicherweise mehr als zwei Spalten enthalten.

Jetzt möchte ich den Datenblock neu formatieren, so dass alle Elemente aus einer bestimmten Spalte in einer einzigen Zeile aufgeführt sind (getrennt durch das Zeichen, das ich im obigen Beispiel als $ markiert habe): Die Elemente aus Spalte 0 füllen Sie Zeile 0, die Elemente aus Spalte 1 füllen Zeile 1 und so weiter.

Gibt es dafür eine vordefinierte emacs-Funktion? Oder wenn nicht, gibt es eine "selbstgerollte" Funktion, um das zu erreichen?

Auch ich bin sehr interessiert an einer Funktion, die die umgekehrte Sache macht, d. H. Einige Zeilen nehmen und sie in die Spaltenstruktur setzen.

Jede Hilfe wird sehr geschätzt!

Antwort

6

Sie können csv-mode (verfügbar von package.el) verwenden. Dies ist eine einfache Transponieroperation. Um dies zu tun, passen Sie den Wert csv-separators an an und verwenden Sie dann C-c C-t.

+0

Diese teilweise funktioniert, nach der Umsetzung fehle ich die Trennzeichen zwischen den verschiedenen Elementen in der Zeile. – elemakil

+0

Es funktioniert hier. Haben Sie customize verwendet, um die Variable zu setzen und emacs neu zu starten? Ich hatte Probleme, als ich die Variable direkt in der Sitzung setzte. –

1

Gerade im Interesse der Praxis:

(defun transpose-table (begin end &optional numcols) 
    (interactive "r\nP") 
    (save-excursion 
    (goto-char begin) 
    (move-beginning-of-line 1) 
    (let ((separators 
      (if numcols 
       (loop for i from 0 upto 
        (if (numberp numcols) numcols (car numcols)) 
        for sep = 
        (read-string 
         (format "%d'th column separator (RET to terminate): " i)) 
        until (string= sep "") 
        collect sep) 
      (let ((x (list " "))) (nconc x x)))) 
      (end (save-excursion 
       (goto-char end) 
       (move-end-of-line 1) 
       (point))) lines) 
     (loop while (< (point) end) 
      for start = (point) 
      for line = (buffer-substring 
         start 
         (progn (move-end-of-line 1) (point))) 
      for numlines from 0 
      with numrows = 0 
      with longest-word = 0 
      collect (loop for i from 0 below (length line) 
          with last-pos = 0 
          with rows = 0 
          with sep = separators 
          for sep-length = (length (car sep)) 
          if (and (< (+ sep-length i) (length line)) 
            (string= (car sep) 
              (substring line i (+ i sep-length)))) 
          collect (substring line last-pos i) into words 
          and do (setf longest-word (max longest-word (- i last-pos)) 
             last-pos (+ i sep-length) 
             sep (cdr sep) rows (1+ rows)) 
          end 
          finally (return 
            (progn 
            (setf numrows (max rows numrows)) 
            (if (< last-pos (length line)) 
             (append words (list (substring line last-pos))) 
             words)))) 
      into lines 
      collect longest-word into word-lengths 
      do (unless (eobp) (forward-char)) 
      finally 
      (loop initially (delete-region begin end) 
        for i from 0 to numrows do 
        (loop for line on lines 
         for cell-length in word-lengths do 
         (if (caar line) 
          (let ((insertion (caar line))) 
           (insert insertion 
             (make-string 
             (- cell-length (length insertion) -1) ?\)) 
           (rplaca line (cdar line))) 
          (insert (make-string (1+ cell-length) ?\)))) 
        (insert "\n")))))) 

Vielleicht das eine vom csv-mode Verwendung wäre eigentlich besser, aber man kann versuchen diese unabhängig :)

Wie es funktioniert: Wenn Sie es nennen wie Mxtranspose-table, davon ausgehen, es wird dann die Tabellenspalten durch einzelne Leerzeichen getrennt werden, aber wenn Sie es mit numerischen Argument (zum Beispiel aufrufen, M-3Mxtranspose-table, dann werden Sie aufgefordert, 3 Spaltentrennzeichen zu sammeln. Man könnte es auch nennen wie C-uC-uM-xtranspose-table, und entscheidet sie aus allen 16 Separatoren Bereitstellung durch Drücken RET wenn für zusätzlichen Separator gefragt.

Ich kann nicht die richtigen Ordnungs Druck von Zahlen Funktion finden ... so, sorry für „1-ten“ und „2'th“ Englisch :)

+0

Dies ist, was ich gesucht habe (etwas unabhängig von dem Modus, den ich derzeit verwende), aber es hat einige Fehler. Für den Anfang scheint es die letzte Spalte zu verlieren. Wenn ich auf zwei Spalten laufe, bekomme ich eine Zeile (mit den Elementen aus der ersten Spalte), arbeite an drei, ich bekomme zwei Zeilen und so weiter. Außerdem scheint es, dass das Präfix-Argument nicht funktioniert, die Ausführung von 'M-3 Mx Transpose-Tabelle' gibt den Fehler 'let *: Wrong type argument: listp, 3' Auch der umgekehrte (Zeile zu Spalten) verliert den letzten Eintrag (8 Zeilen pro Spalte -> 1 Zeile pro "Spalte" -> 7 Zeilen pro Spalte). – elemakil

Verwandte Themen