Some Handy Bash Functions

Probably a couple of times a day I use pipelines like foo | cut -d\ -f3 | sort -u or awk '$5 ~ /foo/ { print $3, $5 }'. Well, while working on an assignment for my study I decided that I had to put an end to this terrible neglect of using Bash’s expressiveness. :)

So, I made two additions to my stable of practical Bash functions:

match_field() Returns a boolean value when a field in a line matches a pattern:

1
2
3
4
5
# match_field <fieldnum> <RE> <line> ; match field in line
function match_field() {
  nf=${1}; re=${2}; shift 2;
  [[ ${!nf} =~ ${re} ]]
}

extract_field() Is a bit like cut, it prints the content of a field in a line:

1
2
# extract_field <fieldnum> <line> ; extract field from line
function extract_field() { nf=${1}; shift; echo ${!nf}; }

Both abuse positional parameters to select fields, expect this to break horribly when using other field separators than default $IFS.

These can be used to make many of the common cut and awk constructs that probably many of us use over and over again:

1
2
3
4
5
6
7
8
9
while read line
do
  if match_field 2 "foo" ${line}
  then
      foo=$(extract_field 1 ${line})
      bar=$(extract_field 3 ${line})
      echo ${bar} ${foo}
  fi
done < ${somefile}

This is equivalent to the awk script:

1
2
3
  ($2 ~ /foo/) {
      print $1, $3;
  }

Not really more efficient in lines of code, indeed. It doesn’t require forking awk, though. So in tight loops, this might be a bit more easy on system resources. That is all moot because this was just another exercise in going Bash all the way. :)

Comments