File Bundles
August 14, 2015
We begin at the end, with what we want the file bundle to look like. Here’s a bundle that contains three files:
#! /usr/bin/scheme --script (define (do-file f) (define (write-line x) (display x) (newline)) (with-output-to-file (car f) (lambda () (for-each write-line (cdr f))))) (for-each do-file '( ("file1" "This is file one" ) ("file2" "File two has an \"embedded quote\"" "and contains two lines." ) ("file3" "Mary had a little lamb." "It's fleece was white as snow." "And everywhere that Mary went" "The lamb was sure to go." ) ))
The first line marks the file as a shell script, and varies with each Scheme implementation. The do-file
function writes a single file. Then the for-each
loops over the remaining files, writing each. The files are stored in a list of lists, with the filename as the head of each list in the list of lists, followed by the lines of the file. Creating the bundle is just a matter of writing the header then processing the input files one-by-one:
(define (write-header) (for-each (lambda (x) (display x) (newline)) '("#! /usr/bin/petite --script" "(define (do-file f)" " (define (write-line x) (display x) (newline))" " (with-output-to-file (car f) (lambda ()" " (for-each write-line (cdr f)))))" "(for-each do-file '("))) (define (do-file f) (display "(") (write f) (newline) (with-input-from-file f (lambda () (do ((x (read-line) (read-line))) ((eof-object? x)) (write x) (newline)))) (display ")") (newline)) (define (bundle out-file . in-files) (with-output-to-file out-file (lambda () (write-header) (for-each do-file in-files) (display "))") (newline))))
This gets confusing, because the input and output are intertwined, but if you keep the output firmly in mind you’ll eventually get it.
Our test is performed at the command prompt:
> cat >file1 This is file one CTRL-D > cat >file2 File two has an "embedded quote" and contains two lines. CTRL-D > cat >file3 Mary had a little lamb. It's fleece was white as snow. And everywhere that Mary went The lamb was sure to go. CTRL-D > scheme (load "bundle.ss") (bundle "testbundle" "file1" "file2" "file3") (exit) > cat testbundle #! /usr/bin/scheme --script (define (do-file f) (define (write-line x) (display x) (newline)) (with-output-to-file (car f) (lambda () (for-each write-line (cdr f))))) (for-each do-file '( ("file1" "This is file one" ) ("file2" "File two has an \"embedded quote\"" "and contains two lines." ) ("file3" "Mary had a little lamb." "It's fleece was white as snow." "And everywhere that Mary went" "The lamb was sure to go." ) )) > chmod +x testbundle > rm file[123] > ./testbundle > cat file1 This is file one > cat file2 File two has an "embedded quote" and contains two lines. > cat file3 Mary had a little lamb. It's fleece was white as snow. And everywhere that Mary went The lamb was sure to go.
We used read-line from the Standard Prelude. You can run the program at http://ideone.com/Eyvq5A.
Python is the new shell..
This creates a self extracting py file:
content of text1.TXT:
hello world
bye world
content of text2.TXT:
test with ‘qoutes’ and all other “stuf” should get ‘””” “””””IUYE754^!^#!%$#!%#*^ escaped..
result of above script is:
This can be run, result is original text files content again.
Two sample files: file1 and file2
file1 contents:
the quick brown fox jumped over the lazy dog
file2 contents:
foo bar baz quux
Usage: