CLI Tools
Fuzzy Find Navigation
Navigating the file system in the command line is much faster with fuzzy finder than doing ls and cd operations. The fzf tool on the CLI by itself is really just a unix filter - it reads data from stdin, performs a transformation or operation on that data, and writes the result to stdout, so that it can be chained with other tools using pipes. To see this, simply run fzf and select a file. The outcome is that the selected file's filepath gets printed to stdout, it doesn't open the file for you like you would think! It's only useful once you chain its output to another tool.
For example, you can use it with find to find a file or directory:
# fuzzy search through files in cwd
find . -type f | fzf
# fuzzy search through folders in cwd
find . -type d | fzf
# fuzzy search with exact match
find . -type f | fzf -e
You can select multiple items in the fzf UI in multi select mode -m with shift + tab key on the file or directory.
To open the fzf selected file for vim, use:
vim `fzf` # open one file selected with fzf
vim -o `fzf -m` # open a list of files selected with fzf multi select in horizontal split windows
A lot of nice key bindings and features are available with the fzf shell integration. A cool feature is the ** sequence to trigger fuzzy finding:
# opens fuzzy finder to let you find exact file if you do not remember the name!
vim ~/.dotfiles/** # hit TAB after the ** to enter fuzzy completion
vim ../** # hit TAB after to select files under parent directory
vim ../fzf** # hit TAB after to find files under parent that match `fzf`
cd ~/** # hit TAB after this!
ssh ** # hit TAB shows possible hostnames fuzzy completed
The key bindings provided by the fzf shell integration are also very powerful. Instead of using ** in the bash command to invoke fzf, a faster way is to just use <Ctrl-T> at the place where you want the file paths to be pasted in, so cd <Ctrl-T> which will invoke fzf. Once you select the files, they will be pasted into the bash command at the place where you invoked fzf. For exclusively jumping directories, you can just use <Alt-C> to invoke fzf and cd directly into the selected directory! The only caveat is that they only start search relative to current working directory, so any directories and files above are not accessible through these shortcuts, you either need to use ../** or ~/** or have some other shortcut set up.
Using the shell integration is so much faster than manually typing in the fzf commands. Most of the time, you just want to find a file path and put that somewhere or cd into a directory, which is where <Ctrl-T> and <Alt-C> shines.
FFmpeg
A really powerful CLI tool available in bash is ffmpeg which is extremely versatile and powerful for working with media files. It can record, process, stream, and process audio and video - as a result it is used under the hood by OBS, VLC, Youtube, Zoom, Audacity etc. and is a good tool for scripting.
# convert video to mp4
ffmpeg -i input.mov output.mp4
# extract audio from video
ffmpeg -i input.mp4 -q:a 0 -map a output.mp3
# resize video
ffmpeg -i input.mp4 -vf "scale=1280:720" output_720p.mp4
# make a gif from part of a video
ffmpeg -i input.mp4 -t 5 -ss 00:00:03 -vf "scale=500:-1" output.gif
ffmpeg is more like a bare metal video editor and media toolkit accessible directly through CLI.
Tmux
Some useful things I have learnt for managing the terminal multiplexer:
For swapping windows, do <Prefix> + : to open up the tmux command then type swap-window -t 1 for swapping the current window with the first window. Use swap-window -s 2 -t 5 to swap src window 2 with target window 5.
The sleep Executable
Commonly provided with GNU coreutils on Linux there is a /usr/bin/sleep executable program. Its function is to pause execution for a specified duration.
You can check where it lives with which:
which sleep
To make the process sleep for 10 seconds:
sleep 10
PBSNodes
Some useful options for PBSNodes I learned while at Argonne:
Job Dependencies
A common case is to want jobs to run in a specific order, for instance to have a job wait until another completes execution. PBSNodes allows for this via dependencies.
The syntax is:
qsub -W depend=<dependency list>
Where <dependency list> is in the format <type>:<arg list>[,<type>:<arg list>]. The <arg list> is simply one or more job IDs in the form <job ID>[:<job ID>] e.g. 2409736:2409737.
There are many dependency types, here are a few:
after:<arg list>- job starts only after all jobs in list have started executionafterok:<arg list>- job starts only after all jobs in list have terminated with no errors
Archiving & Compression
tar Archives
The GNU tar stands for Tape ARchive, and stores files together into a single archive, with the ability to restore individual files from the archive. An archive is essentially a single file that contains the contents of many files, while still preserving information of file names, owners, permissions and such. With tar you both create and extract archives, list its contents, or append new files to the archive.
tar is very common for Unix systems because it was built for Unix, and preserves uid, gid, permissions. To best understand its concepts, highly recommend reading the manual.
The tar tool is solely about bundling files. Note the difference between archiving and compression. Compression can be done on top of archiving in tar, but it is a secondary functionality.
Compressors like gzip by itself cannot do archiving. To compress multiple files into a single file, you must first tar and bundle them together, and then compress the bundled archive, which can all be done in tar.
The most frequently used operations are to create, list, and extract archives using tar, corresponding to -c, -t and -x. You can only use one operational mode per command.
The most frequently used options on top of an operation are --file for specifying the name of the archive file and --verbose, corresponding to -fand-v`. It is recommended to always specify an archive file!
For instances:
# create an archive called archive.tar from files foo and bar
tar -cf archive.tar foo bar
# examine the contents of the archive
tar -tf archive.tar
# extract all files from archive.tar
tar -xf archive.tar
# extract a specific file from archive.tar
tar -xf archive.tar foo
If use the verbose flag with the list operation, you get owner, file size info like ls -l:
tar -tf archive.tar
-rw-r--r-- davidma/davidma 0 2025-11-27 16:59 foo
-rw-r--r-- davidma/davidma 0 2025-11-27 16:59 bar
tar also supports creating and reading compressed tar archives! tar supports compressions from gzip, bzip2, and so on.
To work with compressed formats, simply provide the compression option in the form of a flag during archive creation:
--gzipor-zforgzip--bzipor-jforbzip2--auto-compressor-afor compression based on the file suffix
# select gzip
tar -czf archive.tar.gz foo bar
# autocompress based on the suffix
tar -caf archive.tar.gz foo bar
For extracting compressed files, there is no need to specify the compression type as tar will detect it based off file signature:
tar -xf archive.tar.gz
Extensions like .tgz, .tar, and tar.gz extension indicate it is a tar archive compressed using gzip. Sometimes you might see .tar.bz if it was compressed using bzip.
tar.gz vs zip
The difference between choosing tar.gz or zip mainly boils down to compression size. Since zip compresses each file individually compared to tar.gz which compresses the entire archive, zip typically has larger file sizes.
zip, unzip Compression
zip is a file compression utility that puts one or more compressed files into a zip archive. It's good for packaging files for distribution, archiving files, or compressing files.
Very similar to tar, zip works with zip archives. You can add, update, delete entries within a zip archive.
The main command structure is zip [options] archive inpath inpath ..., where archive specifies the new or pre-existing zip archive to send compressed files to.
The company program to zip for decompression is unzip, which can list, test, or extract files from a zip archive. By default all files and subdirectories are extracted into the current directory. For a different directory, you can specify a -d exdir external directory.
A powerful flag is the -@ flag to compress files taken from stdin:
# store all files from stdin to foo.zip
zip -@ foo
# archive all C source files in current dir
find . -name "*.[ch]" -print | zip -@ source
Package Managers
apt
yum
brew
Resources
fzfintro video here