A few new shell tricks

[Tweet]

As part of my continuing “Bash Fun” series, I have a few more tricks for Terminal junkies. These work in Bash and Zsh, and probably elsewhere.

To use any of these, just put them in a file and source them from your login profile (~/.bash_profile, etc.).

Write a quick Markdown list

This first one is super simple. It just takes a tab-indented list from STDIN and outputs a Markdown bullet list in Terminal. It removes blank lines and maintains indentation using sed.

You can just run qlist and type the list in Terminal, ending input with ⌃d on a blank line, or pipe input in from pbpaste or a file.

The qlistpb alias at the end is just a shortcut for piping the output to the clipboard instead of STDOUT.

qlist: quick markdown list
# output a quick markdown list from stdin to stdout
qlist() {
    sed -E '/^[     ]*$/d'|sed -E 's/^([    ]*)/\1* /'
}
# quick list to clipboard
alias qlistpb="qlist|pbcopy"

Quickly list IP addresses for the current machine

Next, a function to quickly list internal and WAN ip addresses. It uses ifconfig for the local IP, and then dig with the OpenDNS resolver for the WAN address. It works just as well with icanhazip.com using curl -sS icanhazip.com instead of the dig command, but I have more faith in the OpenDNS method being futureproof.

Updated: Thanks to comments from Keith Rollin and Daniel Whicker the script now iterates through all available network interfaces to find one that’s active.

**Also, Kai Wells has created a fish version of lips.

lips: list ip addresses
# l(ist)ips Get local and WAN IP adddresses
# Updated based on comments from Keith Rollin and Daniel Whicker
# $ lips
#    Local IP: 10.0.1.4
# External IP: 41.32.11.102
lips() {
	local interface ip
	for interface in $(networksetup -listallhardwareports | awk '/^Device: /{print $2}'); do
		ip=$(ipconfig getifaddr $interface)
		[ "$ip" != "" ] && break
	done

	local locip extip

	[ "$ip" != "" ] && locip=$ip || locip="inactive"

	ip=`dig +short myip.opendns.com @resolver1.opendns.com`
	[ "$ip" != "" ] && extip=$ip || extip="inactive"

	printf '%11s: %s\n%11s: %s\n' "Local IP" $locip "External IP" $extip
}

Convert HEX to RGB

Lastly, a function to convert hex color string to RGB using printf. This one takes a 6-character hex code (e.g. #faf1cb) and converts it to an RGB string, (e.g. rgb(250,241,203)).

The leading hash (#) is optional and will be cleared out if it exists. The hex string is case-insensitive, so FAF1CB will work as well. If the input given is 3 characters, it will be automatically expanded, doubling each character, so #666 becomes #666666.

If you want to include a CSS transparency indicator in the output (RGBA), you can include a second argument that consists of a float between 0 and 1, e.g. 0.5. hex2rgb 010 .5 becomes rgba(0,17,0,.5).

If you want just the numbers without the rgb(), change the line local css=true to local css=. Then hex2rgb faf1cb returns 250,241,203.

hex2rgb: convert hex color strings to rgb
# Convert hex string to rgb
# @param 1 (String) 3 or 6 character hex string
#   Case insensitive, leading # optional (01a, fff1b1, #ABB)
# @param 2 (Float) optional float from 0 to 1
#   If provided, outputs an rgba() string
#
# $ hex2rgb FA0133
# rgb(250,1,51)
# $ hex2rgb FA0133 .5
# rgba(250,1,51,.5)
hex2rgb() {
    local css=true
    local printstring
    local hex="$(tr '[:lower:]' '[:upper:]' <<< ${1#\#})"
    # Convert ABC to AABBCC
    if [[ $hex =~ ^[A-F0-9]{3}$ ]]; then
        hex=$(sed -e 's/\(.\)/\1\1/g' <<< $hex)
    fi

    # If the first param is a valid hex string, convert to rgb
    if [[ $hex =~ ^[A-F0-9]{6}$ ]]; then
        # If second param exists and is a float between 0 and 1, output rgba
        if [[ -n $2 && $2 =~ ^(0?\.[0-9]+|1(\.0)?)$ ]]; then
            [[ $css ]] && printstring="rgba(%d,%d,%d,%s)" || printstring="%d,%d,%d,%s"
            printf $printstring  0x${hex:0:2} 0x${hex:2:2} 0x${hex:4:2} $2
        else
            [[ $css ]] && printstring="rgb(%d,%d,%d)" || printstring="%d,%d,%d"
            printf $printstring 0x${hex:0:2} 0x${hex:2:2} 0x${hex:4:2}
        fi
    # If it's not valid hex, return the original string
    else
        echo -n $@
    fi
}

For fish users, a simplified version of this function from Kai Wells.

Ryan Irelan has produced a series of shell trick videos based on BrettTerpstra.com posts. Readers can get 10% off using the coupon code TERPSTRA.