5

このケースを考えてみましょう: 次のようなデータがあります。

1.9170000E+03 $ 1.6909110E+00
1.455000000E+03 $ 1.777459E+00
1.1800000E+03 $ 1.8771469E+00
1.0000000E+03 $ 1.9992190E +
00
2.5585915e+00

2 つの列を区切るドル記号は、任意の文字 (特定の数のスペース、\t (タブ) 文字、コンマ、または列を区切る目的で一意に使用されるほぼすべての文字の範囲) であることに注意してください。データに 3 つ以上の列がある可能性があることに注意してください。

ここで、特定の列のすべての項目が 1 つの行にリストされるように、データのブロックを再フォーマットしたいと思います (上記の例で $ としてマークした文字で区切られています): 列 0 の項目が行 0 を埋めます。列 1 の項目が行 1 を埋めます。

それを行うための事前定義されたemacs関数はありますか? そうでない場合、それを達成するための「自己ロール」機能はありますか?

また、逆のことを行う関数、つまりいくつかの行を列構造に入れる関数にも非常に興味があります。

どんな助けでも大歓迎です!

4

2 に答える 2

7

csv-mode(から入手可能)を使用できますpackage.el。これは単純な転置操作です。そのためには、 to の値をカスタマイズしてcsv-separatorsから'("$")を使用しますC-c C-t

于 2013-04-18T16:49:06.943 に答える
1

練習のために:

(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"))))))

からのものを使用する方が実際には良いかもしれませcsv-modeんが、関係なくこれを試すことができます:)

仕組み: として呼び出すとM-xtranspose-table、テーブルの列が 1 つの空白で区切られていると想定されますが、数値引数 (たとえば、 ) で呼び出すと、M-3M-xtranspose-table3 つの列区切り記号を収集するように求められます。のように呼び出すこともでき、追加のセパレーターを求められたときにC-uC-uM-xtranspose-tableを押して、16 個のセパレーターすべてを提供しないようにすることもできます。RET

数字関数の適切な序数印刷が見つかりませんでした...だから、「1番目」と「2番目」の英語でごめんなさい:)

于 2013-04-19T21:32:32.813 に答える