IMHO, column is one of the most underestimated utilities in UNIX. Every utility should output different information if they are running in a terminal or not. That way, shell scripting would be more straightforward.
While column - ts '<tab>' does help, it has some limitations. One can't specify per-column separator, or alignment. Here's where algn comes handy. algn takes a file, and aligns its columns (-a), and uses specified separators to show them (-s). For example, given: 00 00 01 command 00 00 01 commandsssssssssss 00 00 01 commanddddddddddddddddd 600 00 01 command 00 00 01 command 00 00 01 command algn -a ',,,l' -s ':,.' outputs: 00:00.01 command 00:00.01 commandsssssssssss 00:00.01 commanddddddddddddddddd 600:00.01 command 00:00.01 command 00:00.01 command a option receives aligners in the style: '<aligner>,'; where <aligner> is "l" or "r". s option receives separators in the same style: '<separator>'; where <separator> can be any string _except_ one containing one or more commas (this will be fixed). As the comment says, awk program is mostly Steffen Schuler's work; and I thank him. I thought maybe could give it use, so I share it with you. Greetings! #!/bin/sh # Copyright (c) 2006, 2007 Andres Delfino <[EMAIL PROTECTED]> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # awk program is 99% Steffen Schuler's work. name="${0##*/}" exit_status=0 aligners= separators= function show_usage { printf 'Usage: %s [-a aligners] [-s separators] [file ...]\n' "${name}" >& 2 exit 1 } while getopts ':a:s:' ch; do case "${ch}" in ( a ) aligners="${OPTARG}" ;; ( s ) separators="${OPTARG}" ;; ( ? ) printf 'Invalid option.\n' >& 2 show_usage ;; esac done shift "$((${OPTIND} - 1))" awk_program=' \ BEGIN \ { \ FS = " "; \ aligners = split("'"${aligners}"'", aligner, ","); \ separators = split("'"${separators}"'", separator, ","); \ } \ \ { \ for (field = 1; field <= NF; ++field) \ { \ fields[NR,field] = $field; \ field_length = length($field); \ \ if (field_length > max_field_length[field]) \ max_field_length[field] = field_length; \ } \ } \ \ END \ { \ for (record = 1; record <= NR; ++record) \ { \ for (field = 1; record SUBSEP field in fields; ++field) \ { \ if (field > 1) \ if (field - 1 <= separators) \ printf("%s", separator[field - 1]); \ else \ printf(" "); \ \ string = "%"; \ \ if (field <= aligners && aligner[field] == "l") \ string = string "-"; \ \ string = string "*s"; \ printf(string, max_field_length[field], fields[record,field]); \ } \ \ printf("\n"); \ } \ } \ ' if [ "${#}" -ge 1 ]; then while [ "${1}" ]; do if [ -e "${1}" ]; then if [ -f "${1}" ]; then if [ -r "${1}" ]; then awk "${awk_program}" "${1}" else printf '%s: %s: Permission to read from file not granted\n' "${name}" "${1}" >& 2 exit_status=4 fi else printf '%s: %s: File is not a regular file\n' "${name}" "${1}" >& 2 exit_status=3 fi else printf '%s: %s: File does not exist\n' "${name}" "${1}" >& 2 exit_status=2 fi shift done elif ! [ -t 0 ]; then awk "${awk_program}" else show_usage fi exit "${exit_status}"