2010-02-14 7 views
5

Ocasionalmente uso AWK para extraer y/o invertir columnas en un archivo de datos.

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

¿Cómo haré lo mismo con 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 

Muestra filename.txt: salida

a b c 
1 2 5 

muestra:

b , a 
2 , 1 

Respuesta

2

¿Cómo pretende utilizar esto? ¿Estás planeando usarlo como un script de línea de comandos? En ese caso, deberá empaquetarlo así hello world question.

O, usted está planeando sobre el uso de forma interactiva, en cuyo caso es probable que desee la salida en un nuevo buffer ...

Este código se lo básico hecho. Deberá actualizarlo para que coincida con su modelo de uso.

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

He oído que 'con corriente-buffer' debe ser utilizado en lugar de 'save-excursion' y' set-buffer'. – pheaver

+0

¿Es "(-1+ ...)" un error tipográfico? –

+0

@melling Sí, gracias. –

0

Tomé la solución de Trey y produje un script que se ejecuta desde un shell Unix. No toma los parámetros de la línea de comandos porque no estaba seguro de cómo convertir los command-line-args-left resultados en un parámetro adecuado.

 

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

Uso de las funciones de dash.el y 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 

Por defecto, awk trata texto como una secuencia de registros (separados por salto de línea), siendo una secuencia de campos de cada registro (separados por espacio) . Entonces en el ejemplo anterior c es un campo del registro a b c. La función print-columns recibe un texto, se separa por líneas nuevas con s-lines, selecciona ciertos campos de cada registro, los une con una coma con s-join, se une al resultado con nuevas líneas. La función más importante es dash 's -select-by-indices, que recoge elementos de una lista de sus índices y rendimientos en el mismo orden que la lista de índices:

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