Skip to content

Instantly share code, notes, and snippets.

@ernstki
Last active November 7, 2019 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ernstki/68c7b7da28d9a8c9ced7 to your computer and use it in GitHub Desktop.
Save ernstki/68c7b7da28d9a8c9ced7 to your computer and use it in GitHub Desktop.
fawk: a Bash shell function to save your fingers from typing awk '{ print $x }' all the time
#!/bin/bash
##############################################################################
## ##
## fawk! - a shortcut for `awk '{ print $x }'` ##
## (also an expression of extreme frustration) ##
## --------------------------------------------- ##
## ##
## Author: Kevin Ernst <ernstki -at- mail.uc.edu> ##
## Inspiration: http://serverfault.com/a/5551 (but basically rewritten) ##
## Mnemonic: "Field Awk" ##
## ##
##############################################################################
function fawk() {
local file last rest=()
local GIST='https://gist.github.com/ernstki/68c7b7da28d9a8c9ced7'
local USAGE="
usage: fawk [-h|--help] [<awk_args>] <field_no> [<filename>]
examples: $ ps | fawk 2 | sort -u # list all ttys in use
$ fawk -F: 7 /etc/passwd | sort -u # all users' shells
$ getent passwd | grep andy | fawk -F: 5 # get Andy's GECOS info
feedback: $GIST
"
# set TRACE=1 in the environment for debugging
(( ${TRACE:-} )) && set -x
# no arguments, or -h / --help
if [[ $# -eq 0 ]]; then
echo "$USAGE" >&2
return 1
elif [[ $1 =~ ^--?h ]]; then
echo "$USAGE"
return
fi
# Store off the *last* argument given on the command line
last="${@:(-1)}"
# remember all but the last
if [[ $# -gt 1 ]]; then
# Source: https://tinyurl.com/yxelzloj (cyberciti.biz)
rest=( ${@:1:$(( $# - 1 ))} )
fi
# If the last argument is a readable "thing" (file, process substitution,
# pipe), then the argument before it needs to be a number.
if [[ -r $last ]]; then
# Test to see if we still have enough arguments:
if [[ $# -lt 2 ]]; then
echo >&2
echo "FAWK! Insufficient arguments (need 2). Try '--help'." >&2
echo "$USAGE" >&2
return 1
fi
file=$last
# New $last is the final element of $rest
last=${rest[@]:(-1)}
# Pop last element of $rest (using Bash index operator)
rest=( "${rest[@]:0:$(( ${#rest[@]} - 1 ))}" )
# make sure the new last argument was an integer
if [[ $last =~ [^0-9] ]]; then
echo >&2
echo "FAWK! When giving a filename, the second-to-last"\
"argument (Awk field) must be numeric." >&2
echo "$USAGE" >&2;
return 1
fi
# bail if the *last* argument isn't a number (see
# http://stackoverflow.com/a/808740 for a Bourne-compatible technique)
elif [[ $last =~ [^0-9] ]]; then
echo >&2
echo "FAWK! Unless you give a filename, the last argument (Awk"\
"field) must be numeric." >&2
echo "$USAGE" >&2;
return 1
fi
# $file might be the empty string; in that case, Awk will wait for stdin
awk "${rest[@]}" "{ print \$$last }" ${file:+"$file"}
} # fawk
# only if it's invoked like a script
[[ $0 == ${BASH_SOURCE[0]} ]] && fawk "$@"
# fawk
@ernstki
Copy link
Author

ernstki commented Nov 21, 2014

Yes, getent passwd | grep andy | fawk -F: 5 wastes a precious process, and could be done in pure AWK anyway

getent passwd | awk -F: '/andy/ { print $5 }'

but... those braces... are so hard to type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment