首页 > 解决方案 > Wrap a single oversize column with awk / bash (pretty print)

问题描述

Im having this table structure (assume that the delimiters are tabs):

AAA  BBBB  CCC
 01  Item  Description here
 02  Meti  A very very veeeery long description which will easily extend the recommended output width of 80 characters.
 03  Etim  Last description

What i want is this:

AAA  BBBB  CCC
 01  Item  Description here
 02  Meti  A very very veeeery
           long description which
           will easily extend the
           recommended output width
           of 80 characters.
 03  Etim  Last description

That means I want to split $3 into an array of strings with predefined WIDTH, where the first element is appended "normally" to the current line and all subsequent elements get a new line width identation according to the padding of the first two columns (padding could also be fixed if thats easier).

Alternatively, the text in $0 could be split by a GLOBAL_WIDTH (e.g. 80 chars) into first string and "rest" -> first string gets printed "normally" with printf, the rest is split by GLOBAL_WIDTH - (COLPAD1 + COLPAD2) and appended width new lines as above.

I tried to work with fmt and fold after my awk formatting (which is basically just putting headings to the table) but they do not reflect awk's field perceptance of course.

How can I achieve this using bash tools and / or awk?

标签: bashawkpretty-print

解决方案


首先构建一个测试文件(称为file.txt):

echo "AA  BBBB  CCC
01  Item  Description here
02  Meti  A very very veeeery long description which will easily extend the recommended output width of 80 characters.
03  Etim  Last description" > file.txt

现在脚本(称为./split-columns.sh):

#!/bin/bash
FILE=$1

#find position of 3rd column (starting with 'CCC')
padding=`cat $FILE | head -n1 |  grep -aob 'CCC' | grep -oE '[0-9]+'`
paddingstr=`printf "%-${padding}s" ' '`

#set max length
maxcolsize=50
maxlen=$(($padding + $maxcolsize))

cat $FILE | while read line; do 
  #split the line only if it exceeds the desired length
  if [[ ${#line} -gt $maxlen ]] ; then 
    echo "$line" | fmt -s -w$maxcolsize - | head -n1
    echo "$line" | fmt -s -w$maxcolsize - | tail -n+2 | sed "s/^/$paddingstr/"
  else
    echo "$line";
  fi; 
done;

最后将文件作为单个参数运行

./split-columns.sh file.txt > fixed-width-file.txt

输出将是:

AA  BBBB  CCC
01  Item  Description here
02  Meti  A very very veeeery long description
          which will easily extend the recommended output
          width of 80 characters.
03  Etim  Last description

推荐阅读