Bash is super powerful.

File System Full

Show Remaining Space on Drives


df -h

show largest files in current directory


du . -h --max-depth=1

Move files then symlink them


mkdir /mnt/mounted_drive
mv ~/bigdir /mnt/mounted_drive
ln -s /mnt/mounted_drive/bigdir ~/bigdir

Fuzzy One Liners


a() {source activate "$(conda info --envs | fzf | awk '{print $

edit in vim


vf() { fzf | xargs -r -I % $EDITOR % ;}

cat a file


vf() { fzf | xargs -r -I % $EDITOR % ;}

bash execute


bf() { bash "$(fzf)" }

git add


gadd() { git status -s | fzf -m | awk '{print $2}' | xargs git add && git status -s}

git reset


greset() { git status -s |  fzf -m | awk '{print $2}' |xargs git reset && git status -s}

Kill a process


fkill() {kill $(ps aux | fzf | awk '{print($2)}')}

Finding things

Files

fd-find is amazing for finding files, it even respects your .gitignore file ๐Ÿ˜ฒ. Install with apt install fd-find.


fd md

ag -g python

find . -n "*.md"

++Vanilla Bonus

Content

** show matching text **


ag python

grep -iR Python

++Vanilla Bonus

** show file names only **


ag -l python

grep -iRl python

++Vanilla Bonus

Recursively Replace text


agr() {ag -l "$1" | xargs sed -i "s/$1/$2/g"}

++Vanilla Bonus


grepr() {grep -iRl "$1" | xargs sed -i "s/$1/$2/g"}

Extending **agr** or **grepr**

There are so many options inside of grep, ag, and sed that you could many an enormous amount of these if you really wanted to, but I like to keep it simple. These cover 90% of my usage. If I wanted to change something in the second half I would just paste in this command and edit it. More often though I want to limit the input, say only replace word1 to word2 inside of markdown files.

Limited Scope


fd md | xargs argr python python3

find . -n "*.md" | xargs grepr python python3

++Vanilla Bonus

refactor-in-cli

I use these replace commands heavily when doing large refactorings.

conditionally configure

I like this one when there is not a good cli into config files and I need to replace something like a true to false if the value is in the config and append to the config if its not.


grepr() {
    # replaces first string with second string inside file from third argument
    # example:
    #   grepr "allow_conda_downgrades:.*" "allow_conda_downgrades: true" ~/.condarc
    if grep -xq $1 $3
    then
        sed -i "s|$1|$2|g" $3
    else
        echo "$2" >> $3
    fi
}

Watch the time


watch -n 1 date

++Vanilla Bonus

with figlet


watch -n 1 bash -c "date | figlet"

watch a function


run () {
date
aws s3 sync $BUCKET .
}
export -f run
watch -n 10 run

if conda environment does not exist create it


conda info --envs | grep my_env && echo "my_env environment is installed" || conda create -n my_env python=3.8 -y
source activate my_env

Rename multiple files

more info from linuxize


for f in *.png; do
   mv ${f} prefix-${f}
done

using the rename command


sudo apt install rename

rename "s/.GIF/.gif/" *.GIF

convert all files in a directory to unix


dos2unix **/*

recursively remove all whitespace from .py files


find **/*.py -type f -exec sed -i 's/ *$//' '{}' ';'

recursively autopep8


find . -name '*.py' -exec autopep8 --in-place '{}' \;

make bash script a runnable command

include a shebang


#! /bin/bash

chmod


chmod +x /usr/local/bin/my_script

accept positional input


#! /bin/bash
input=$1
echo input

Using pyp


pipx install pyp

replacement for cut


โฏ python -m http.server 5000 &
[1] 8574

โœฆ โฏ Serving HTTP on 0.0.0.0 port 5000 (http://0.0.0.0:5000/) ...

โœฆ โฏ ps aux | grep "python -m http.server" | grep -v grep | pyp 'line.split()[1]' | xargs kill
[1]  + terminated  python -m http.server 5000

replacement for wc


conda info --envs | pyp 'len(lines) - 3 # account for header and base'

declare -f <function-name>

batch rename files


for f in *.jpeg; do
    mv -- "$f" "${f%.jpeg}.jpg"
done

convert markdown files to reveal.js

https://github.com/jgm/pandoc/wiki/Using-pandoc-to-produce-reveal.js-slides install pandoc


apt install pandoc

setup


wget https://github.com/hakimel/reveal.js/archive/master.tar.gz
tar -xzvf master.tar.gz
mv reveal.js-master reveal.js

convert


pandoc -t revealjs -s -o myslides.html myslides.md -V revealjs-url=https://unpkg.com/[email protected]/

Render Markdown at the command line

Glow is a terminal markdown renderer written in go. There iis a prebuilt binary that can simply be unzipped and executed to render markdow.


wget https://github.com/charmbracelet/glow/releases/download/v0.2.0/glow_0.2.0_linux_x86_64.tar.gz
tar -xzf glow_0.2.0_linux_x86_64.tar.gz
chmod +x glow
sudo mv glow /usr/bin

glow <filename>

Autocomplete for click applications

see the docs for more details

Autocomplete for non click python cli's

shtab https://github.com/iterative/shtab

Ensure functions reset context


project_log() {
   _dir=$(pwd)
   _project_log() {
      cd ~/projects/project
      git log
   }
   _project_log $@ && cd $_dir || cd $_dir
}

Finding Files


rg --files . | grep bash
rg --files . | rg bash
rg --files . | ag bash
rg --files . | fzf
rg -e 'hook' -g '*.md'
rg -e 'hook' -g '*.py'

rg --files-with-matches
rg --files-without-match

mu-repo


# installation
pip install mu-repo

## register repos
mu register --recursive
mu list

# run git commands
mu status --short
mu diff -U0 --color | bat

# run shell commands
mu sh $(grep -iRl "KEDRO_GID=0" | xargs sed -i "s/KEDRO_GID=0/KEDRO_GID=5/g")

mu-repo

See the full post for mu-repo for more

mu unregister all

I ran into some issues with mu unregister * before, but this seems to work everywhere.


mu list | tail -n +3 | xargs -I {} mu unregister {}

mu register all repos that have an rg match

Add all repos that have a versionspec of 3.7 in them.


rg --hidden=true 'versionSpec:.*.3.7' -l | xargs -I {} mu register {}

xrandr


xrandr -s 1920x1080