考虑这种情况:我有一些看起来像这样的数据:
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
请注意,分隔两列的美元符号可以是任何字符(范围从一定数量的空格,\ t(制表符)字符,逗号或任何唯一用于分隔列的字符)另请注意,数据可能包含两列以上。
现在我想重新格式化数据块,使得某一列中的所有项都列在一行中(由我在上面示例中标记为$的char分隔):第0列中的项填充第0行,第1列中的项填充第1行,依此类推。
是否有预定义的emacs功能?或者如果没有,是否有一些“自动滚动”功能来实现这一目标?
此外,我对一个执行相反操作的函数非常感兴趣,即取一些行并将它们放在列结构中。
非常感谢任何帮助!
答案 0 :(得分:7)
您可以使用csv-mode
(package.el
提供)。这是一个简单的转置操作。为此,请自定义csv-separators
到'("$")
的值,然后使用 C-c C-t 。
答案 1 :(得分: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
中的那个实际上会更好,但无论如何都可以尝试这个:)
如何工作:如果你将其称为 Mx transpose-table
,那么它将假设表列由单个空格分隔,但是,如果使用数字参数调用它(例如, M-3 Mx transpose-table
,然后它将提示您收集3个列分隔符。您也可以将其称为 Cu Cu Mx transpose-table
,当要求提供额外的分隔符时,按 RET 选择不提供所有16个分隔符。
我找不到合适的序号打印功能......所以,对不起“1”和“2”英语:)