Shell script to convert CSV to HTML tables (updated)

Here's an updated version of a previously posted shell script that uses awk to convert a delimited file (where delimiter can be any character) to HTML tables.

For a little automation project I did, the script needed to process input from a pipe, instead of file. So this updated version adds an "-f" option to get delimited data from a file, or "-" option to get it from STDIN.

#!/bin/bash

usage()
{
cat < and  tags.

  --foot   Treat last line as footer, enclosing in  and  tags. 

  --help   Print this help message.

Examples:

  1. $(basename $0) -f input.csv

  Above will parse file 'input.csv' with comma as the field separator and
  output HTML tables to STDOUT.

  2. $(basename $0) -d '|' - < input.psv > output.htm

  Above will parse file "input.psv", looking for the pipe character as the
  delimiter, then output results to "output.htm".

  3. $(basename $0) -d '\t' --head --foot -f input.tsv

  Above will parse file "input.tsv", looking for tab as the delimiter, then
  process first and last lines as header/footer (that contain data labels).

  4. sed 's/|/,/g' input.psv | $(basename $0) -

  In this example, file "input.psv" is pre-processed in sed, then output is
  sent to $(basename $0), with the "-" option, to use STDIN as source of
  delimited data.

EOF
}

while [ "$1" ]; do
  case "$1" in
    -d)
      shift
      d="$1"
      ;;
    -f)
      shift
      f="$1"
      ;;
    --foot)
      foot="-v ftr=1"
      ;;
    --help)
      usage
      exit 0
      ;;
    --head)
      head="-v hdr=1"
      ;;
    -f)
      shift
      f="$1"
      ;;
    -)
      data=$(cat -)
      ;;
    -*)
      echo "ERROR: unknown option '$1'"
      echo "see '--help' for usage"
      exit 1
      ;;
  esac
  shift
done

if [ -z "$d" ]; then
  d=","
fi

if [ -f "$f" ]; then
  data=$(sed '/^$/d' $f)
else
  data=$(sed '/^$/d' <<< "$data")
fi

last=$(wc -l <<< "$data")

awk -F "$d" -v last=$last $head $foot '
  BEGIN {
    print "  "
  }       
  {
    gsub(//, "\\>")
    if(NR == 1 && hdr) {  
      printf "    \n"
    gsub(/&/, "\\>")    }
    if(NR == last && ftr) {  
      printf "    \n"
    }
    print "      "
    for(f = 1; f <= NF; f++)  {
      if((NR == 1 && hdr) || (NR == last && ftr)) {
        printf "        \n", $f
      }
      else printf "        \n", $f
    }     
    print "      "
    if(NR == 1 && hdr) {
      printf "    \n"
    }
    if(NR == last && ftr) {
      printf "    \n"
    }
  }       
  END {
    print "  
%s%s
" } ' <<< "$data"

Leave a comment

NOTE: Enclose quotes in <blockquote></blockquote>. Enclose code in <pre lang="LANG"></pre> (where LANG is one of these).