file helper for shells
fh, or file helper, adds to the functionality of cp and mv in bash. If you regularly move between directories, or have multiple windows open to various directories, fh allows you to copy/move files between them easily. The examples below explain its functionality.
git clone https://github.com/tylerneylon/fh.git
sudo ln -s $(cd fh; pwd)/fh.py /usr/local/bin/fh
~/path/one$ fh = . # Select all files in this directory.
~/path/one$ cd ../two
~/path/two$ fh + foo* *.png # Also select matching files.
~/path/two$ cd ../foo
~/path/two$ fh ls # Print out what was selected.
+ /Users/tylerneylon/path/one/ as *
+ /Users/tylerneylon/path/two/foo1 as foo1
+ /Users/tylerneylon/path/two/foo2 as foo2
+ /Users/tylerneylon/path/two/1.png as 1.png
+ /Users/tylerneylon/path/two/2.png as 2.png
~/path/foo$ fh cp # Copy those files here.
When fh is given a path to a directory, it always treats that path as the full contents of the directory, including everything recursively. Non-obvious file sets can be expressed using file exclusion (the - action).
Suppose we want to copy most of a directory over, but not all of it:
$ fh = mydir
$ fh - mydir/.git # Exclude the .git subdirectory.
$ cd ~/destination/
$ fh cp # Copies over mydir less .git.
When you type fh - <subpath>
, you exclude
everything in <current dir>/<subpath>
recursively.
You can also specify custom filesets
using standard bash glob notation, as in
fh = a* b* g* m{a,e}*
.
Suppose you have three terminal windows open, and execute each of these commands in a separate window:
(window 1) ~/a/b/c$ fh = file1 file2 dir1
(window 2) ~/d/e/f$ fh + file3 dir2 dir3
(window 3) ~/g/h/i$ fh mv
Then file{1,2,3}
and dir{1,2,3}
will all be moved,
including everything recursively in the directories,
to ~/g/h/i
.
Suppose two bash scripts both start with fh = X
and end with fh [cp|mv]
. They can still call
each other and work correctly. In the standard
GUI cut-and-paste model, any new copied/cut selection
erases the old one, but fh keeps around a stack
of filesets, so that nested filesets (pushed via
the = action) will be remembered and act as
expected.
The stack of filesets are stored in the text file
~/.fhstack
. If you want to reset the state of
fh
, you can safely delete this file.
In general, fh
is used like this:
$ fh [action] [option(s)] [path/file(s)]
where action
determines what happens.
action | what it does |
---|---|
= |
push a new fileset onto fh's stack |
+ |
add files to the current fileset |
- |
exclude files from the current fileset |
ls |
list the current fileset |
cp |
copy the current fileset to . and pop it from fh's stack |
mv |
move the current fileset to . and pop it from fh's stack |
diff |
diff . with the current fileset (fileset is not popped) |