awk '{print $2,",",$1}'在 Emacs Lisp 中?

发布于 2024-08-21 10:18:25 字数 636 浏览 3 评论 0 原文

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

Occasionally I use AWK to extract and/or reverse columns in a data file.

awk '{print $2,",",$1}' filename.txt

How would I do the same using 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

Sample filename.txt:

a   b  c
1   2  5

Sample output:

b , a
2 , 1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柠檬 2024-08-28 10:18:25

您打算如何使用这个?您打算将其用作命令行脚本吗?在这种情况下,您需要像 hello world 问题 那样打包它。

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

此代码完成了基础知识。您需要更新它以匹配您的使用模型。

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

How do you intend to use this? Are you planning on using it as a command-line script? In which case, you'll need to package it like this hello world question.

Or, are you planning on using it interactively, in which case you probably want the output in a new buffer...

This code gets the basics done. You'll need to update it to match your usage model.

(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)))
一袭水袖舞倾城 2024-08-28 10:18:25

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

I took Trey's solution and produced a script that runs from a Unix shell. It doesn't take command line parameters because I wasn't sure how to convert the command-line-args-left results into a proper parameter.


#!/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)

素衣风尘叹 2024-08-28 10:18:25

使用 dash.els.el

(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 是记录ab c 的一个字段。函数 print-columns 接收文本,用换行符分隔 s-lines,从每条记录中选择某些字段,用逗号将它们与 s-join,用换行符连接结果。最重要的功能是 dash-select-by-indices,通过索引从列表中选取元素,并以与索引列表相同的顺序返回:

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

Use functions from dash.el and s.el:

(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

By default, awk treats text as a sequence of records (separated by newline), each record being a sequence of fields (separated by space). So in the above example c is a field of the record a b c. The function print-columns receives a text, separates by newlines with s-lines, selects certain fields from each record, joins them with a comma with s-join, joins the result with newlines. The most important function is dash's -select-by-indices, which picks elements from a list by their indexes and returns in the same order as the list of indices:

(-select-by-indices '(2 1 0) '(a b c d e)) ; => (c b a)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文