Some Oddball Shell & Vim Tricks I've Acquired Over the Years

Hello, hashnode!

My name is Matt, and I'm an engineering manager. It's a 2022 resolution of mine to try to write more. I am taking the easy way out with my first post — rather than spend a bunch of time writing on some topic, I'm just dumping a bunch of one liners and tricks I've acquired over the last couple years into this post.

Maybe this will be useful, maybe it will not be, but it accomplishes a goal of publishing my first blog post in 2022 so I'm doing it regardless!

Prerequisites

Some of these expect that you have the following tools installed:

Shell

Generate a UUID

Add this function to your .zshrc / .bash_profile to generate a UUID on-the-fly:

get-uuid () {
    curl -k -s "https://www.uuidgenerator.net/api/version4" | sed 's/[^[:print:]\r\t]/ /g'
}

To use it, do e.g. get-uuid | pbcopy (on a Mac) to generate a UUID and put in on your clipboard.

YAML

ruby -ryaml -e "p YAML.load(STDIN.read)" < myfile.yml

Kubectl

Run kubectl diff on all files containing a search term:

for s in $(grep -rl searchterm ./dir/subdir); do kubectl --context=context diff -f $s; done;

Get colored (and foldable) kubectl diff output via vim (based on this GitHub issue comment):

vdiff () {
    /usr/bin/vim -R -c 'set syntax=diff' -;
}

Use like kubectl --context=$CONTEXT -f path/to/manifest.yaml | vdiff

CSV/JSON

Turn one column of a CSV file into a properly quoted JSON array of strings:

csvcut -c 3 file.csv | jq --raw-input --slurp 'split("\n")[1:-1]'

Java

Change between multiple installed JDK versions. Use like jdk 13 or jdk 1.8 (from AdoptOpenJDK on GitHub).

jdk() {
    local VERSION=$1
    export JAVA_HOME=$(/usr/libexec/java_home -v"$VERSION");
    java -version
}

Git

Remove files from git if they're present in the .gitignore file (from StackOverflow):

git rm --cached `git ls-files -i -X .gitignore`

List all files which have been committed in the current git repository:

git ls-tree --full-tree -r --name-only HEAD

Get the default branch name for a repository (substitute organization for your organization name):

get-default-branch () {
    gh repo view organization/"$1" --json defaultBranchRef | jq --raw-output '.defaultBranchRef.name'
}

Clone a git repository if it does not exist locally, or navigate into it and pull latest default branch if it does exist locally. This uses the above get-default-branch function:

gclone () {
    local REPOSITORY="$1"
    REPO_PATH="$HOME/dev/$REPOSITORY"
    if [ -d $REPO_PATH ]
    then
        cd "$REPO_PATH"
        DEFAULT_BRANCH=$(get-default-branch "$REPOSITORY")
        git checkout "$DEFAULT_BRANCH"
        git fetch --all && git reset --hard origin/"$DEFAULT_BRANCH"
    else
        cd "$WORKING_DIR"
        git clone "git@github.com:payitgov/$REPOSITORY" && cd "$REPO_PATH"
    fi
}

Use it like:gclone my_service.

NPM

Alias the npm version command to not do git tags, and to skip any preversion scripts that might be in place in the repository (I don't want to wait for a test suite to run just to increment the version!).

vermp() {
    npm version "$1" --no-git-tag-version --ignore-scripts
}

Use like vermp major vermp minor vermp patch.

AWK

Find rows in one file which contain values present in another file:

Assume ids.txt looks like:

5871795
5872036
...

And data.txt looks like:

5871794^350182^300003^BFT CNTY SCHOOL^300009^0^BOND-1033^50^0^50^0.03171^1.59^0^1.59^0
5871795^350181^300000^5% Interest Pen^300000^0^5% INTEREST PENALTY^270^0^270^0^0^0^0^0
awk -F '^' 'NR==FNR {id[$1]; next} $1 in id' ids.txt data.txt > data_containing_ids.txt

oh-my-zsh

Put this in your .zshrc file to improve performance of pasting into the terminal, as by default in o-m-z it's very slow, and scales linearly with length of pasted input.

pasteinit() {
  OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
  zle -N self-insert url-quote-magic
}

pastefinish() {
  zle -N self-insert $OLD_SELF_INSERT
}
zstyle :bracketed-paste-magic paste-init pasteinit
zstyle :bracketed-paste-magic paste-finish pastefinish

Emacs

If you are a weirdo like me who sometimes edits an orgmode file outside emacs, and you want to run the org-tangle blocks that it contains, use this shell function. Use like tangle myfile.org.

tangle () {
    emacs --batch -l org "$1" -f org-babel-tangle
}

Vim

Strip the BSON ISODate wrapper from a MongoDB document if you copied a document as BSON rather than as text/JSON:

:%s/ISODate(\(".*"\))/\1/

Open all files (in tab pages) that contain a search term: ( -p for tab pages, -o/-O for horizontal/vertical windows or whatever).

 vim -p `grep -rl 'searchterm' ./dir --color=never`

Prettify XML in vim:

:%!xmllint --format %

Prettify JSON in vim:

%!jq '.'