awk&x27;{打印$2,“,”,“,$1}';在Emacs Lisp中?

awk&x27;{打印$2,“,”,“,$1}';在Emacs Lisp中?,awk,elisp,Awk,Elisp,有时我会使用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 c

有时我会使用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

你打算如何使用这个?您是否计划将其用作命令行脚本?在这种情况下,您需要像这样包装它

或者,您是否计划以交互方式使用它,在这种情况下,您可能希望输出在新的缓冲区中

这段代码完成了基础工作。您需要更新它以匹配您的使用模型

(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)))
(defun awk(文件名和rest cols)
给定文件名和至少一列,打印列值
按指定列的顺序。”
(let*((buf(查找文件noselect文件名)))
(带当前缓冲区buf)
(同时(<(点)(最大点))
(let((拆分字符串(缓冲子字符串(行开始位置)(行结束位置)))
(c科尔斯)
逗号)
(c)
(如果是逗号
(以“,”号填列)
(印刷品(第n(1-(c车))件)
(setq逗号t)
(setq c(cdr c)))
(打印“\n”)
(前线)
(杀死缓冲区buf)))

我采用了Trey的解决方案,并生成了一个从Unix shell运行的脚本。它不接受命令行参数,因为我不确定如何将命令行参数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)
使用和中的函数:

默认情况下,awk将文本视为一系列记录(以换行符分隔),每条记录都是一系列字段(以空格分隔)。因此,在上面的示例中,
c
是记录
abc
的字段。函数
print columns
接收文本,用换行符分隔,从每条记录中选择特定字段,用逗号连接,用换行符连接结果。最重要的函数是
dash
,它通过索引从列表中选取元素,并以与索引列表相同的顺序返回:

(-select-by-indices '(2 1 0) '(a b c d e)) ; => (c b a)

我听说应该使用带当前缓冲区的
而不是
保存偏移
设置缓冲区
。为什么要在每列后面打印换行符?您确定要在打印一行中所有选定列之后再打印它吗?
(-select-by-indices '(2 1 0) '(a b c d e)) ; => (c b a)