有时我会使用AWK提取和/或反转数据文件中的列。
awk '{print $2,",",$1}' filename.txt
我如何使用Emacs Lisp做同样的事情?
(defun awk (filename col1 &optional col2 col3 col4 col5)
"Given a filename and at least once column, print out the column(s)
values in the order in which the columns are specified."
...
)
;; Test awk
(awk "filename.txt" 1); Only column 1
(awk "filename.txt" 2 1); Column 2 followed by column 1
(awk "filename.txt" 3 2 1); Columns 3,2 then 1
示例filename.txt
:
a b c
1 2 5
示例输出:
b , a
2 , 1
答案 0 :(得分:2)
你打算如何使用它?您是否计划将其用作命令行脚本?在这种情况下,您需要像hello world question一样打包它。
或者,您是否计划以交互方式使用它,在这种情况下,您可能希望将输出放在新缓冲区中...
此代码完成了基础知识。您需要更新它以符合您的使用模式。
(defun awk (filename &rest cols)
"Given a filename and at least once column, print out the column(s) values
in the order in which the columns are specified."
(let* ((buf (find-file-noselect filename)))
(with-current-buffer buf
(while (< (point) (point-max))
(let ((things (split-string (buffer-substring (line-beginning-position) (line-end-position))))
(c cols)
comma)
(while c
(if comma
(print ", "))
(print (nth (1- (car c)) things))
(setq comma t)
(setq c (cdr c)))
(print "\n")
(forward-line))))
(kill-buffer buf)))
答案 1 :(得分:0)
我采用了Trey的解决方案并生成了一个从Unix shell运行的脚本。它不需要命令行参数,因为我不确定如何将命令行-args-left 结果转换为适当的参数。
#!/usr/bin/emacs --script
;; ./awk.el; # Change the last line of this file to contain the desired values.
;;
(defun awk (filename &rest cols)
"Given a filename and at least once column, print out the column(s) values
in the order in which the columns are specified."
(let* ((buf (find-file-noselect filename)))
(with-current-buffer buf
(while (< (point) (point-max))
(let ((things (split-string (buffer-substring (line-beginning-position)
(line-end-position))))
(c cols)
comma)
(while c
(if comma
(princ ", "))
(princ (nth (1- (car c)) things))
(setq comma t)
(setq c (cdr c)))
(princ "\n")
(forward-line))))
(kill-buffer buf)))
(awk "/tmp/foo.txt" 2 1)
答案 2 :(得分:0)
(defun print-columns (s &rest is)
(s-join "\n"
(--map (s-join ", "
(-select-by-indices is (cons it (s-split " " it t))))
(s-lines s))))
(print-columns "a b c\n1 2 3" 3 2 1 0) ; output:
;; c, b, a, a b c
;; 3, 2, 1, 1 2 3
默认情况下,awk将文本视为一系列记录(由换行符分隔),每个记录都是一系列字段(由空格分隔)。因此,在上面的示例中,c
是记录a b c
的字段。函数print-columns
接收文本,按换行符s-lines
分隔,从每条记录中选择某些字段,用逗号s-join
连接它们,将结果与换行符连接起来。最重要的函数是dash
的{{3}},它通过索引从列表中选择元素,并以与索引列表相同的顺序返回:
(-select-by-indices '(2 1 0) '(a b c d e)) ; => (c b a)