[racket] simple scripting with Racket

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Sat Jul 20 11:14:34 EDT 2013

Here is a slightly more compact version, still not scsh syntax: 

#! /bin/sh
#|
exec racket -tm "$0" ${1+"$@"}
|#
#lang racket

;; ---------------------------------------------------------------------------------------------------
;; this script replaces "," in "stem.csv" files with "." and places the result in "stem-ms.csv" 
;; current directory only 

(provide main)

(define (main)
  ;; use (in-directory), if you would like recursion in file system 
  (for ((f (directory-list)) #:when (regexp-match? #rx"[^-ms]\\.csv" f))
    (define in (open-input-file f))
    (define ff (regexp-replace #rx"\\." (path->string f) "-ms."))
    (define out (open-output-file ff #:exists 'replace #:mode 'text))
    (parameterize ((current-input-port in) (current-output-port out))
      (for ((l (in-lines)))
	(printf "~a\n" (regexp-replace #rx"\\." l ","))))
    ;; skip, if you don't expect too many files: 
    (close-input-port in)
    (close-output-port out)))

;; a test run: 

s% !!
rm -rf foo-ms.csv ; cat foo.csv ; ./replace.rkt ; cat foo-ms.csv
1, "hello . world", 10
1, "hello , world", 10

Does this help a bit? -- Matthias






On Jul 20, 2013, at 7:04 AM, Vlad Kozin wrote:

> Hi. I thought I'd use Racket to solve a silly little scripting problem. 
> 
> Script doesn't take arguments, instead looks for .csv files in its directory, reads them line by line, does some trivial replacement and writes the result to a new .csv file adding "-ms" suffix to its name. You can see my solution http://pastebin.com/CPb5gxEu and below. I suppose you bearded hackers would roll-out a quick awk + sh script in a minute - seems like exactly the task suited for awk. Unfortunately I find I'm allergic to sh - entirely too much of a challenge for me. Plus .csv files I'm dealing with are on the order of >200Mb. 
> 
> Writing it felt somewhat awkward or rather more so than I anticipated, hence this post. Can you see a better, more straightforward, canonical way of doing this sort of things? Feels like general-purpousness of the language shows and a dsl like scsh would allow more straightforward style.  
> 
> #! /usr/bin/env racket
> #lang racket
> 
> ;; doesn't tell directories and files apart, can be dangerous
> (define files
>   (filter
>    (lambda (e) (regexp-match? #rx"[^-ms]\\.csv" e))
>    (directory-list (current-directory))))
> 
> ;; this really should be a straightforward pipe with processing in the middle
> ;; this wrapping of with--file procedures feels a little like writing cps by hand
> ;; (stdin stdout) now point to (in out)
> (define (with-in-out-files proc in out)
>   (with-input-from-file in
>     (lambda ()
>       (with-output-to-file out proc  #:mode 'text #:exists 'replace))))
> 
> (define (replace-dot-in-file in)
>   (define (dot->comma)
>     (for ([l (in-lines)])
>       (printf "~a\n"   (regexp-replace #rx"\\." l ","))))
>   (define (out-filename file suffix)
>     (define file-ext  (regexp-split #rx"\\." file))
>     (string-append (first file-ext) suffix "." (second file-ext)))
>   (with-in-out-files dot->comma in (out-filename in "-ms")))
> 
> ;; good candidate to exploit that multi-core bazooka
> ;; should I be using futures / places / threads and 
> ;; some kind of parallel map here? 
> (time (for-each replace-dot-in-file files))
> 
> Thanks
> 
> 
> 
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130720/3b693822/attachment-0001.html>

Posted on the users mailing list.