Package: wrld
You may think thatwrldis some abbreviated form of “world”. This is
not the case. The world is lame. What isn’t lame is iterating onstdin.
Probably my favorite thing to do. In the shell, the sanest way to do
this is with awhile read line; doloop. Forget the world.wrldis the future of iteration.Raise your hand if you have ever written this loop:find-name'*foo.bar'-typef|whilereadline;domv"$line""$(echo"$line"|sed's/pat/rep/')"doneOr the related loop:foriin*foo.bar;docp...# I'm too lazy even to finish this example.doneNote:if you have ever written a loop that starts with the wordsfor i in $(ls ..., you’re doing it wrong. Do one of the above instead.  (also,
thewhile read line; doversion can also fail if there are
filenames with newlines, which you might have if you’re iterating on
filenames generated by an idiot.)Withwrld, you can write like this:find-name'*foo.bar'-typef | wrld mv {} '@sed"s/pat/rep/"'. You can do something similar with
globs as well:wrld mv {} '@sed"s/pat/rep/"'-f*foo.barThis is
manifestly better for one-liners in the shell.You could also think of it asxargs-I{}or the-execflag fromfindon steroids, because it iterates on stdin, but it also allows
inlining arbitrary shell commands.$ls|wrldmv{}'@awk "{print $2, $1}"'mv'Arnold Palmer''Palmer Arnold'mv'Jane Doe''Doe Jane'mv'John Doe''Doe John'mv'John Wayne''Wayne John'mv'Lucy Lawless''Lawless Lucy'mv'Ricki Lake''Lake Ricki'As you can see, inlined commands have the current line piped to their
stdin. If you want to use some poorly-designed command that doesn’t read
from stdin as the filter, you can also substitute{}for the current
line.  Use\{}if you need a literal ‘{}’. However, if you can’t do
it with sed or awk, there’s alwaysperl-pe, and if you can’t do it
withperl-pe, I don’t want to know about it. You can also see thatwrldechos back the commands it constructs. You can shut it up with-q/--no-echo. You can also do a “test run” to see what the
generated commands will be without actually running them, using-t/--testflags.Because POSIX stupidly allows newlines in file names, this is
actually a “dangerous” example unless can guarantee there are no idiot
newlines in the file names. For this reason, you may instead specify a
list of file names to iterate over (like, preferably with a glob) with
the -f/–file-list flag:$wrldmv{}'@awk "{print $2, $1}"'-f*mv'Doe Jane''Jane Doe'mv'Doe John''John Doe'mv'Lake Ricki''Ricki Lake'mv'Lawless Lucy''Lucy Lawless'mv'Palmer Arnold''Arnold Palmer'mv'Wayne John''John Wayne'If you’re using a proper shell like fish or zsh, you can do recursive
globbing and get quite a lot done this way.One day, in the far distant future, wrld may support splitting stdin
on the null byte for compatibility withfind-print0. It is a
little know fact that any task which a computer is capable of
preforming may be prefomed with thefindcommand, so compatibility
is key.flagswrld is stupid about flags with the command it wraps. However, courtesy
ofargparse, you can tell wrld that no further flags are coming with
the--argument.$find-typed|wrld--mv-v{}/some/dir...optimizeNote:I/O bound tasks will not benefit much from these optimizations.As you may note, wrld is capable of spawning a lot of processes. If it’s
some quick thing, who cares? If your iterating over a million files, it
might be bad. wrld offers some internal goodies to speed things along,
but they are written in python, so don’t expect any miracles! (kind of
kidding. A few lines of python is way faster than spawning a new
process, but it would be much slower than piping a million lines strait
throughsedor whatever optimized C utility).These builtins are for certain common file operations: they have names
like “move”, “copy”, “hlink” and “slink”.movemoves files recursively. It’s likemvwithout any
options.copycopies files recursively. It’s likecp-R.hlinkcreates hard links. Hard links basically give the same chunk
of data more than one name on the filesystem. It’s called a “hard”
link because of the physiological responce many people experience when
they realize how powerful this idea can be.slinkcreates soft links. These are about like shortcuts on the
great and glorious Windows operating system. They are called “soft”
links because of what happens to you when you realize the original
file has moved and all your links are broken. You never have this
problem with “hard” links, but you can’t use them across different
partitions/devices or on directories, so, eh.srlinkexpand relative paths to absolute paths when soft linking.
Likeln-sr.removeremove stuff. recursively. take care.makedirmakes directories… works likemkdir-pOther builtins may be added as they occur to me or users ask for them.mv,cpandlnare commands I frequently find myself needing
in these kinds of loops.Another way to optimize is by using|as a prefix to your filters,
rather than@; i.e.wrld move {} '|awk "{print $2,$1}"'-f*.
This opens a single process ofawk, filters stdin through that, and
then zips the results together with the main loop. This will create
problems if the filter produces no output for certain lines of input
(likegrepwould, though I don’t know why you’d use grep in a
context like this…), or if you have filenames with newlines, like a
freak. So, it will work in most cases. One day I may implement this
properly with asyncronous piping, so this won’t be a problem.Note that, until this becomes an asyncronous pipe, this is a speed
enhancement, but piping in this way consumes additional memory, which
may make it infeasable for very large tasks in a low memory environment.There are also two buitin filters.@pyallows you to use arbitrary
python expressions as a filter. The current line or filename is
available in the execution context asi.$wrldmove{}'@py i.upper()'-f*move'Arnold Palmer''ARNOLD PALMER'move'Jane Doe''JANE DOE'move'John Doe''JOHN DOE'move'John Wayne''JOHN WAYNE'move'Lucy Lawless''LUCY LAWLESS'move'Ricki Lake''RICKY LAKE'@pyuses a little namespace magic that will import any module you
happen to use in your expression on demand. Note that only expressions
and not statements are supported.@pycombined with-fshould
also do the right thing with newlines in file names.The other builtin filter iss. The syntax looks a bit likesed,
but it’s python regex, so refer to the relevant docs if you’re not
already familiar with it. It’s based on Perl, like the regex in most
popular programming langauges (and unlike sed), but it has a few of its
own quirks.$wrldmove{}'s/[aeiou]/λ/g'-f*move'Arnold Palmer''Arnλld Pλlmλr'move'Jane Doe''Jλnλ Dλλ'move'John Doe''Jλhn Dλλ'move'John Wayne''Jλhn Wλynλ'move'Lucy Lawless''Lλcy Lλwlλss'move'Ricki Lake''Rλckλ Lλkλ'It accepts any flags that can be used in a python regex in the contex of(?[flags]), so,aiLmsux. In addition, thegflag is
supported, to make it more similar to sed and Perl. While/is used
as the delimiter by convention, any non-alphanumeric character may be
used.If the replacement is prefixed with\e, a python expresison can be
used, wheremis the re.match object for each match, so that offers
some interesting possibilities.I can neither confirm nor deny that there may be another filter in my
mind for doing awk-like things based on python’sstr.filtermethod.