Marcel: A Modern Shell
Marcel is a shell. The main idea is to rely on piping as the primary means of composition, as with any Unix or Linux shell. However, instead of passing strings from one command to the next, marcel passes Python values: builtin types such as lists, tuples, strings, and numbers; but also objects representing files and processes. A pipe carries streams of these values between ccommands.
Example: Find the five file types, under the current directory, taking the most space.
M 0.18.3 jao@loon ~/git/marcel$ ls -fr \
M +$ | map (f: (f.suffix, f.size)) \
M +$ | select (ext, size: ext != '') \
M +$ | red . + \
M +$ | sort (ext, size: size) \
M +$ | tail 5
('.exe', 2414592)
('.pack', 2510550)
('.pyc', 5845056)
('.json', 8478723)
('.py', 22104759)
What this does:
-
ls -fr: List the files (-f) recursively (-r) in the current directory.
-
|: Pipe result to the next operator.
-
map (...): Given a file piped in from the ls command, return a tuple containing the file's extension (suffix) and size.
-
select (...): Pass downstream files for which the extension is not empty.
-
red . +: Group by the first element (extension) and sum the second one (file sizes).
-
sort (...): Given an (extension, size) tuple, sort by size.
-
tail 5: Keep the last five tuples from the input stream.
So this finds all files recursively, gets the extension and size of each, (discarding files without extensions), sum file sizes by extension, sort by size, and show the last five, i.e., the five extensions taking the most space.
To explore marcel, read this tutorial.