: ########################################################################## # Shellscript: wordwrap - wrap lines on word boundaries # Author : Heiner Steven # Date : 2001-12-10 # Requires : # Category : Text Utilities, Text Formatting # SCCS-Id. : @(#) wordwrap 1.5 18/05/17 ########################################################################## # Description # A very simple text formatting program. The input is read # word by word. All words are joined using a space (ASCII # 32) character. If "-j" was specified, each line is # filled up to the maximum line length, or the next empty # line before it is printed. Each continued line can be # offset by a number of blanks. # # Note # o Leading whitespace is ignored # o An AWK program actually formats the input. It is written in # a way to be portable to a wide range of AWK dialects. # o thanks for Samus-Aran for suggesting the "-l" option # # Caveats # o Should have an option for keeping whitespace inbetween words ########################################################################## PN=`basename "$0"` # Program name VER='1.5' # Uncomment the following line to disable the search for the fastest AWK #: ${AWK:=awk} DEFWIDTH=72 # Default line length DEFOFFSET=0 # Default continued line offset DEFMARGIN=0 # Default left margin Usage () { echo >&2 "$PN - wrap lines on word boundaries, $VER usage: $PN [-j] [-w width] [-o offset] [-l margin] [file ...] -j join multiple lines up to the maximum line length -l left margin (default $DEFMARGIN) -o offset of continued lines (default $DEFOFFSET) -w max. line width (default is $DEFWIDTH characters)" exit 1 } Msg () { for MsgLine do echo "$PN: $MsgLine" >&2 done } Fatal () { Msg "$@"; exit 1; } ########################################################################## # searchprog - search program using search PATH # usage: searchprog program ########################################################################## searchprog () { _search=$1; shift for _dir in `echo "$PATH" | sed "s/^:/.:/;s/:\$/:./;s/::/:.:/g;s/:/ /g"` do [ -x "$_dir/$_search" ] || continue echo "$_dir/$_search" return 0 done return 1 } # isint - is argument a valid integer number? isint () { case "$1" in *[!0-9]*) return 1;; *) return 0;; esac } set -- `getopt :hjl:o:w: "$@"` || Usage [ $# -lt 1 ] && Usage # "getopt" detected an error # Search for an AWK implementation, prefer the fastest one : ${AWK:=`searchprog mawk || searchprog gawk || searchprog nawk || echo awk`} LineWidth= JoinLines=false LeftMargin= while [ $# -gt 0 ] do case "$1" in -j) JoinLines=true;; -l) isint "$2" || Fatal "invalid margin: $2" LeftMargin=$2; shift;; -o) isint "$2" || Fatal "invalid offset: $2" LineOffset=$2; shift;; -w) isint "$2" || Fatal "invalid line width: $2" LineWidth=$2; shift;; --) shift; break;; -h) Usage;; -*) Usage;; *) break;; # First file name esac shift done : ${LineWidth:=$DEFWIDTH} : ${LineOffset:=$DEFOFFSET} : ${LeftMargin:=$DEFMARGIN} $AWK ' BEGIN { WORDSEP = " " WORDSEPLEN = length (WORDSEP) maxwidth = '"$LineWidth"' if ( "'"$JoinLines"'" == "true" ) joinlines = 1; else joinlines = 0; line = "" offset = '"$LineOffset"' margin = '"$LeftMargin"' if ( offset >= 1 ) indent = sprintf ("%*s", offset, " ") if ( margin >= 1 ) leftmargin = sprintf ("%*s", margin, "") } { # Special handling: preserve leading whitespace characters if ( line == "" ) { for ( i=1; i 1 ) line = substr ($0, 1, i-1) } for ( i=1; i<=NF; ++i ) { newlen = length (line) + length ($i) if ( line != "" ) newlen += WORDSEPLEN if ( newlen > maxwidth ) { print leftmargin line line = indent $i } else { if ( line != "" ) line = line WORDSEP line = line $i } } # No joining of lines: print the current line immediately if ( !joinlines || NF == 0 ) { print leftmargin line if ( line != "" && NF == 0 ) print "" # preserve empty line line = "" } } END { if ( line != "" ) { print leftmargin line } } ' "$@"