https://github.com/dannguyen/bashfoo
Dan Nguyen's personally curated list of bash/command-line commands and snippets that are useful but yet he keeps forgetting
date
add a UTC timestamp in ISO-8601 format to a filenamedu
recursively list directories and their disk space sizeffmpeg
convert a video to gifffmpeg
encode .mkv video to .mp4ffmpeg
optimize video and reduce its file sizeffmpeg
resize a video and preserve its aspect ratiofind
and execute command on each filefind
and list the top 10 most recently modified subdirectoriesfind
and tally total kilobytes of hard disk space for files with given extension(s)find
directory name recursivelyfind
file by namemagick
convert image to favicon.icoogr2ogr
convert a shapefile into CSV + GeoJSONpandoc
convert a Markdown file into a Word docxpgrep
and get all process infopkill
using a file patternprintf
to stderrpygmentize
a code snippet into highlighted rich text that I can paste into GMailrsync
the contents of one directory into anotherssh-add
a new SSH key to system ssh-agent (macOS)stem
a filename, i.e. get filename sans path or extensiontar
extraction, verboseunzip
only an archive's CSV files and pipe to stdoutxargs
(BSD) to pipe results into another command, one at a timeyoutube-dl
to download just a video's transcript/subtitle files
# Example
# Just the current UTC date using GNU date, i.e. gdate on macOS
printf "mydata_%s.csv\n" $(gdate --utc -I)
# >>>> mydata_2021-08-03.csv
# UTC date with hours+minutes, GNU and BSD compatible
printf "mydata_%s.csv\n" $(date -u +"%Y-%m-%d-%H%M")
# >>>> mydata_2021-08-03-1248.csv
References:
# Example
# GNU du (verbose)
du --human-readable --max-depth=2 ./bashfoo
# GNU du (concise) / BSD du (i.e. MacOS)
du -h -d 2 ./bashfoo
Output:
2.4M ./bashfoo/.git/objects
4.0K ./bashfoo/.git/info
44K ./bashfoo/.git/logs
48K ./bashfoo/.git/hooks
16K ./bashfoo/.git/refs
2.6M ./bashfoo/.git
3.6M ./bashfoo/assets/samples
3.6M ./bashfoo/assets
6.3M ./bashfoo
References:
- List all directories and sort by size
- How to sort human readable size
- How to replace Mac OS X utilities with GNU core utilities?
Notes:
More variations and usecases for GNU du:
List only directories of a minimum size
# (concise) $ du -t 3M ./bashfoo
$ du --threshold 3M ./bashfoo
3660 bashfoo/assets/samples
3728 bashfoo/assets
6436 bashfoo/
Specify a size unit, e.g. K, M, G for: kb, mb, gb
# (concise) $ du -B M ./bashfoo
$ du --block-size M ./bashfoo
1M ./bashfoo/.git/objects/61
...
1M ./bashfoo/assets/samples/chicago_neighborhoods
4M ./bashfoo/assets/samples
4M ./bashfoo/assets
7M ./bashfoo/
List largest 5 directories using human-numeric-sort
$ du -h ~/Downloads | sort -h -r | head -n 5
2.6G /Users/me/Downloads
851M /Users/me/Downloads/ebooks
233M /Users/me/Downloads/OLD_JUNK
25M /Users/me/Downloads/names
9.5M /Users/me/Downloads/bootstrap-4.5.2
# Example
# minimalist conversion (infinite looping GIF, i.e. -loop=0, is the default)
ffmpeg -i input.mp4 output.gif
# yes-to-overwrite, 15 frames-per-second
# scaled to 225px wide w/ lanczos scaler, and non-looping
ffmpeg -y -i input.mp4 \
-vf "fps=15,scale=225:-1:flags=lanczos" -loop -1 \
output.gif
# generate a palette png file that favors areas with motion
ffmpeg -y -i input.mp4 -vf "palettegen=stats_mode=diff" palette.png
# and then use that palette png
ffmpeg -y -i input.mp4 -i palette.png -lavfi paletteuse output.gif
References:
- How do I convert a video to GIF using ffmpeg, with reasonable quality?
- Optimizing GIFS with FFMPEG
- High quality GIF with FFmpeg
# Example
ffmpeg -i input.mkv -acodec aac -vcodec libx264 output.mp4
References:
# Example
ffmpeg -i my_video.mp4 -vcodec libx264 -crf 28 my_video_optimized.mp4
References:
# Example
# to rescale a video's width to 450 pixels and autoscale its height
ffmpeg -i in_video.mp4 -vf scale=450:-2 out_video.mp4
# to rescale a video's height to 204 pixels and autoscale its width
ffmpeg -i in_video.mp4 -vf scale=-2:204 out_video.mp4
# Note that the given pixel width/height should be an even number
# to avoid getting an error like: height not divisible by 2 (500x201)
References:
# Example
find ./PATTERN -exec FOO BAR {} \;
find PlainText/*.md -exec wc -l {} \;
References:
# Example
find ~/a -mindepth 1 -maxdepth 2 -type d \
-not -name '_*' -not -name '.*' \
-print0
| xargs -0 -n1 -I{} \
stat -f '%Sm %N' -t '%Y-%m-%d %H:%M:%S' {} \
| sort -rn | head -n10
# GNU variant, e.g. with gnu-coretools on macOS
gfind . -mindepth 1 -maxdepth 2 -type d \
-not -name '_*' -not -name '.*' \
-printf '%T+ %p\n' \
| sort -rn \
| head -n 10
Output:
2020-11-27 14:05:45 /Users/dan/Downloads/r-book
2020-09-25 11:39:45 /Users/dan/Desktop/sf-shelter-data
2020-06-18 22:45:15 /Users/dan/Downloads/journalism-syllabi
2020-08-26 20:16:55 /Users/dan/Desktop/vocal-samples
2020-07-09 14:48:38 /Users/dan/Downloads/svelte-project
2020-07-09 14:29:43 /Users/dan/Desktop/matplotlibguide
2020-05-29 22:00:28 /Users/dan/Downloads/buzzfeed-archives
2020-03-18 14:57:03 /Users/dan/Downloads/transcribe-texts
2020-01-18 05:55:32 /Users/dan/Desktop/oldstuff
2020-01-17 16:43:39 /Users/dan/Desktop/random_images
References:
# Example
echo $(find . -type f \
\( -iname "*.csv" -o -iname '*.xls*' \) \
-printf "(%k/1024)+" \
2>/dev/null; \
echo 0;) | bc
Output:
15732
References:
Notes:
- Requires the use of gnu-find (gfind on my MacOS)
- use
-printf "%s+"
to print size by bytes 2>/dev/null
hides error messages-iname
is case-insensitive
# Example
find START_DIR -type d -name "PATTERN"
References:
# Example
find . -name "foo*"
References:
# Example
magick /tmp/testimage.png -background none -resize 128x128 -density 128x128 favicon.ico
References:
# Example
ogr2ogr -f CSV \
-dialect sqlite \
-sql 'SELECT *, AsGeoJSON(geometry) AS geom FROM chicago_neighborhoods' \
chicago_neighborhoods_output.csv \
chicago_neighborhoods.shp
References:
Notes:
Chicago neighborhood shapefile comes from the city data portal
Download a copy of the zipped shapefile: chicago_neighborhoods.zip
This is what a shapefile converted into CSV looks like: chicago_neighborhoods_output.csv
# Example
pandoc README.md -f markdown -t docx -o README.docx
References:
# Example
# MacOS
pgrep -fil 'rails'
# Linux
pgrep -af 'rails'
Output:
47502 rails master RBENV_VERSION=2.5.1 TERMINAL_FONT=Monaco
47517 rails worker[0] RBENV_VERSION=2.5.1 TERMINAL_FONT=Monaco
References:
# Example
pkill -fil ipython
Output:
kill -15 90396
kill -15 90523
References:
# Example
>&2 printf 'Error: %s\n' 'There was a problem' 'And another problem'
Output:
Error: There was a problem
Error: And another problem
References:
# Example
# Converting plaintext to rich-text format and copying to clipboard
printf "SELECT 1, 2, 3 \nFROM table;" \
| pygmentize -f rtf -l sql \
| pbcopy
# Producing a PNG of a code snippet, using the "vim" stylesheet,
# 36-point font (default is 14), 21px line spacing (default is 2px),
# and highlighting lines 2, 4, and 6 in hot pink (line numbers are on by default)
printf 'SELECT *\n\t, name, id\nFROM\n\tdTable AS Texas\nWHERE\n\tid > "Howdy"\nORDER BY\n\tname DESC;' \
| pygmentize -f png -l sql \
-O 'style=vim' \
-O 'font_size=36,line_pad=21' \
-O 'hl_color=hotpink,hl_lines=2 4 6' \
> assets/pretty-pyg-sql.png
Example of rich-text format (-f rtf
) being pasted into GMail:
Example of writing pygmentize into PNG file:
References:
Notes:
- install via pip:
pip install --upgrade Pygments
- Use
-L
to get your installed version of pygmentize's most complete list of all styles, formatters, and lexers
# Example
rsync -ahv --progress src_dir/ target_dir
Output:
building file list ... done
created directory /target_dir
./
.gitignore
README.md
static/media/
static/media/demos/
static/media/demos/find.mp4
sent 452477 bytes received 2378 bytes 50909710.00 bytes/sec
total size is 472016 speedup is 1.00
References:
Notes:
- only the source directory should have a trailing slash
-v
makes for verbose output-n
does a dry run-z
compresses files--progress
provides a progress bar-u
updates only the destination files older than the source filesh
human-readable numbers
# Example
# put this in bash profile
eval "$(ssh-agent -s)"
# note: use -t rsa -b 4096 if system doesn't support Ed25519 algorithm
ssh-keygen -t ed25519 -C "justme@example.com" \
-f ~/.ssh/myid_as_ed25519
# add key to ssh-agent and store passprhase in keychain
$ ssh-add -K ~/.ssh/myid_as_ed25519
Output:
Agent pid 59566
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/justme/.ssh/myid_as_ed25519.
Your public key has been saved in /Users/justme/.ssh/myid_as_ed25519.pub.
The key fingerprint is:
SHA256:9zABCDEx9sp+zyxTestTest+LoremIpsum justme@example.com
The key's randomart image is:
+--[ED25519 256]--+
|. .. . .o.|
| .o.. .o .o .|
| |
| ..o + + = * |
| |
|B o |
| o... o . . .+|
| ...T o +o.|
| oo. . .== |
+----[SHA256]-----+
References:
- Generating a new SSH key and adding it to the ssh-agent
- How can I change the directory that ssh-keygen outputs to?
Notes:
May need to edit ~/.ssh/config to point to non traditional IdentityFile location, e.g.
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/myid_as_ed25519
# Example
fullname=/tmp/hello/world.txt
newname="a_whole_new_$(basename ${fullname%.*})"
echo $newname
Output:
a_whole_new_world
References:
# Example
tar xzfv ARCHIVE.TAR.GZ
References:
# Example
unzip -p schools.zip "*.csv" > schools.csv
# Example
echo Alice Bob Charlie | xargs -I{} -n1 echo 'Hey, {} is a great name!'
Output:
Hey, Alice is a great name!
Hey, Bob is a great name!
Hey, Charlie is a great name!
References:
# Example
youtube-dl --write-sub --skip-download https://www.youtube.com/watch?v=PMp_-OX15Jc
Output:
[youtube] PMp_-OX15Jc: Downloading webpage
[youtube] PMp_-OX15Jc: Downloading MPD manifest
[info] Writing video subtitles to: What is Public Domain-PMp_-OX15Jc.en.vtt