2010-02-14 21 views
5

Gelegentlich verwende ich AWK, um Spalten in einer Datendatei zu extrahieren und/oder umzukehren.

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

Wie würde ich das gleiche mit Emacs Lisp tun?

(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 

Probe filename.txt:

a b c 
1 2 5 

Beispielausgabe:

b , a 
2 , 1 

Antwort

2

Wie wollen Sie diese nutzen? Planen Sie, es als Befehlszeilenskript zu verwenden? In diesem Fall müssen Sie es so verpacken hello world question.

Oder sind Sie es über die Verwendung interaktiv planen, in diesem Fall sind Sie wahrscheinlich die Ausgabe in einem neuen Puffer wollen ...

Dieser Code wird die fertig Grundlagen. Sie müssen es aktualisieren, damit es Ihrem Nutzungsmodell entspricht.

(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

Ich habe gehört, dass' mit strom buffer' sollte anstelle von 'save-excur' und' set-buffer' verwendet werden. – pheaver

+0

Ist "(-1+ ...)" ein Tippfehler? –

+0

@melling Ja, danke. –

0

Ich nahm Treys Lösung und produzierte ein Skript, das von einer Unix-Shell ausgeführt wird. Es dauert keine Befehlszeilenparameter, weil ich nicht sicher war, wie man die command-line-args-left Resultate in einen korrekten Parameter umwandelt.

 

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

Verwenden Funktionen aus dash.el und 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 

Standardmäßig behandelt Text als eine Folge von Datensätzen (durch Neue-Zeile getrennt) AWK jeder Datensatz eine Abfolge von Feldern (getrennt durch Leerzeichen) wobei . Also im obigen Beispiel c ist ein Feld des Datensatzes a b c. Die Funktion print-columns empfängt einen Text, trennt durch Zeilenumbrüche mit s-lines, wählt bestimmte Felder aus jedem Datensatz aus, verbindet sie mit einem Komma mit s-join, verbindet das Ergebnis mit Zeilenumbrüchen. Die wichtigste Funktion ist dash ‚s -select-by-indices, die Elemente aus einer Liste von ihrem Indizes und kehrt in der gleichen Reihenfolge wie die Liste des Indizes nimmt:

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