8 tabularize - Takes TAB-delimited lines of text and outputs formatted table.
12 I<COMMAND> | tabularize [I<OPTIONS>]
24 borders with nice graphical chars
26 =item -H, --no-horizontal
28 no horizontal lines in the output
30 =item -M, --no-margins
32 no margins, ie. no right-most and left-most vertical borders
34 =item -v, --output-vertical-separator I<CHAR>
36 vertical separator character(s) in the output
38 =item -r, --align-right I<NUM>
40 align these columns (0-indexed) to the right,
41 others are auto-detected and if deemed to contain numeric data,
42 only then aligned to the right.
43 this option is repeatable.
45 =item -l, --align-left I<NUM>
47 similar to --align-right option
57 If B<$PAGER> is set and standard output is a terminal
58 and the resulting table is wider than the terminal,
59 then pipe the table through B<$PAGER>.
103 declare -a columnAlignment
=()
124 columnAlignment
[$1]=right
128 columnAlignment
[$1]=left
130 -v|
--output-vertical-separator)
148 echo "$0: unknown option: $1" >&2
161 declare -g -a EXPLODE_ARRAY
=()
163 while [ -n "$string" ]
165 EXPLODE_ARRAY
+=("${string%%$separator*}")
166 new_string
=${string#*$separator}
167 if [ "$string" = "$new_string" ]
174 # return $EXPLODE_ARRAY
177 is_numeric_check_sep
()
179 local thousands_sep
=$2
180 local fraction_sep
=$3
181 [[ $1 =~ ^
[+-]?
[0-9]+($thousands_sep[0-9]+)*($fraction_sep[0-9]+($thousands_sep[0-9]+)*)?$
]]
185 is_numeric_check_sep
"$1" ',' .
&& return 0
186 is_numeric_check_sep
"$1" ' ' , && return 0
187 is_numeric_check_sep
"$1" '.' , && return 0
192 # compute width of each column
198 non_numericals_by_col
=()
201 text
="$text${text:+$'\n'}$line"
202 explode $
'\t' "$line"
205 for cell
in "${EXPLODE_ARRAY[@]}"
208 if [ -z "${column_width[$column]}" ] ||
[ $width -gt "${column_width[$column]}" ]
210 column_width
[$column]=$width
213 # guess if this cell has numerical content (skip 1st line as it's likely a header)
214 if [ $num_line -gt 0 -a -n "$cell" -a -z "${columnAlignment[$column]:-}" ]
216 if is_numeric
"$cell"
218 let numericals_by_col
[$column]++
220 let non_numericals_by_col
[$column]++
231 # no input, no output
238 # compose the format string
247 for column in "${!column_width[@]}"
249 if [ -z "${columnAlignment[$column]:-}" ]
251 if [ ${numericals_by_col[$column]:-0} -ge ${non_numericals_by_col[$column]:-0} ]
253 columnAlignment
[$column]=right
255 columnAlignment
[$column]=left
259 table_width
=$
[table_width
+ (column == 0 ?
(0${margins:+1} ? ${#verticalBar} : 0) : ${#verticalBar}) + ${column_width[$column]}]
261 cellFmt
="${cellFmt:-${margins:+$verticalBar}}${sequentColumn:+$verticalBar}%*s"
262 topFmt
="${topFmt:-${margins:+$topleftCorner}}${sequentColumn:+$topCross}%${column_width[$column]}s"
263 innerFmt
="${innerFmt:-${margins:+$leftCross}}${sequentColumn:+$middleCross}%${column_width[$column]}s"
264 bottomFmt
="${bottomFmt:-${margins:+$bottomleftCorner}}${sequentColumn:+$bottomCross}%${column_width[$column]}s"
269 table_width
=$
[table_width
+ (0${margins:+1} ?
${#verticalBar} : 0)]
270 cellFmt
="$cellFmt${margins:+$verticalBar}"
271 topFmt
="$topFmt${margins:+$toprightCorner}"
272 innerFmt
="$innerFmt${margins:+$rightCross}"
273 bottomFmt
="$bottomFmt${margins:+$bottomrightCorner}"
279 if [ $horizontalLines ]
281 topGrid
=`printf -- "$topFmt" "${segments[@]}"`
282 topGrid
=${topGrid// /$horizontalBar}$
'\n'
283 innerGrid
=`printf -- "$innerFmt" "${segments[@]}"`
284 innerGrid
=${innerGrid// /$horizontalBar}$
'\n'
285 bottomGrid
=`printf -- "$bottomFmt" "${segments[@]}"`
286 bottomGrid
=${bottomGrid// /$horizontalBar}$
'\n'
302 explode $
'\t' "$line"
304 for column in "${!column_width[@]}"
306 [ $column -lt ${#EXPLODE_ARRAY[@]} ] && cell
=${EXPLODE_ARRAY[$column]} || cell
=''
308 bytes
=`LANG=C; echo "${#cell}"`
309 swidth
=$
[ ${column_width[$column]} + ( $bytes - $chars ) ]
310 [ ${columnAlignment[$column]} = left
] && swidth
=-$swidth
311 printf_args
+=($swidth "$cell")
313 printf -- "$cellFmt\n" "${printf_args[@]}"
318 echo -n "$bottomGrid"
322 if [ -t 1 -a -n "$PAGER" ]
324 terminal_cols
=`tput cols`
325 if [ "${terminal_cols:-0}" -le $table_width ]
327 print_table_g |
exec "$PAGER"
328 exit ${PIPESTATUS[1]}