Skip to main content

CLI Tricks: Full justify text with awk

I wanted to do some full-justification of text. So a little awk later, I could set the desired width and pipe to justify it.

#!/usr/bin/awk -f
BEGIN {c = "COLUMNS" in ENVIRON ? ENVIRON["COLUMNS"] : 80}
{
    if (NF > 1) {
        s = $0
        wc = split(s, a)
        gsub(FS, "", s)
        totalfill = c - length(s)
        fill = totalfill / (wc - 1)
        intfill = int(fill)
        errdelta = fill - intfill
        err = 0.5
        printf(a[1])
        for (i=2; i<=length(a); i++) {
            width = intfill
            err += errdelta
            if (err >= 1) {
                ++width
                err -= 1
            }
            printf("%*s%s", width, " ", a[i])
        }
        printf("\n")
    } else print
}

To use, first make sure to set the execute bit with chmod +x full-justify.awk and you can then run it with:

./full-justify.awk example.txt
COLUMNS=60 ./full-justify.awk example.txt

If a line is longer than COLUMNS it will end up ragged rather than reflow. To get around this, first use fmt to reformat the file to the desired width, and then pass it to full-justify.awk

fmt -w40 example.txt | COLUMNS=40 ./full-justify.awk