Reformatting FreeBSD cal(1) with awk(1) ===== cal(1) in FreeBSD can't print month starting with Monday. ncal(1) can do it but it prints weeks vertically which is quiet uncomfortable. So let's try a simple usage of awk(1) to modify cal(1). First of all, we need to remove unprinted characters from cal output. To see them do: $ cal | cat -e June 2021 $ Su Mo Tu We Th Fr Sa $ 1 2 3 4 5 $ 6 7 8 _^H _^H9 10 11 12 $ 13 14 15 16 17 18 19 $ 20 21 22 23 24 25 26 $ 27 28 29 30 $ Underlining character with _^H is the way FreeBSD highlights console symbols, but it don't work in plaintext or in pipe. Besides it's awkward to work with extra field in a current week, so remove it with sed(1). But we can't just print '^H' because it isn't '^H' for real. ^H means raw character code here. To insert this raw character into sed match field we need to press Ctrl+V and then press needed key (Backspace here): $ cal | cat -e | sed 's/_^H//g' June 2021 $ Su Mo Tu We Th Fr Sa $ 1 2 3 4 5 $ 6 7 8 9 10 11 12 $ 13 14 15 16 17 18 19 $ 20 21 22 23 24 25 26 $ 27 28 29 30 $ Everything is good now, so exclude 'cat -e' from pipe further. First line of output should not be modified, but we need to reprint second line with a Sunday at the and of it. Start using awk here and place code to mcal.sh: $ cat mcal.sh cal | sed 's/_^H//g' | awk ' NR == 1 { print }; NR == 2 { print "Mo Tu We Th Fr Sa Su " } ' NR and NF are variables generated by awk. They mean number of rows and number of fields in a current row respectively. The main thought of reformatting cal is to move Sunday column to the end of week and next up it a one day higher. The easiest way to do it in a one pass is to print day of Sunday, then print '\n', and then print the rest of days: { printf "%2s \n%2s %2s %2s %2s %2s %2s ", $1, $2, $3, $4, $5, $6, $7; } or { printf "%2s \n", $1; for (i = 2; i <= NF; i++) printf "%2s ", $i; } While fourth and fifth lines always contain seven fields, third line can contain less. In case first day of month falls on a Sunday (7 days in first week), this day must be printed in the end of third line (2 + 6 * 3 = 20 characters in a string): NR == 3 && NF == 7 { printf "%20s \n", $1; for (i = 2; i <= NF; i++) printf "%2s ", $i; } In case first week of month contains less then 7 days, we need to just remove three initial spaces in it's line and reprint it without final newline symbol: NR == 3 && NF < 7 { sub(/^.../, ""); sub(/ $/, ""); printf "%s", $0; } Function sub(regexp, substitute, string) replaces regexp with substitute in a string (whole current string by default). Second usage of sub() here removes last space in a string printed by cal. The rest of strings of cal output can be processed as shown earlier. Put it all together, combine some actions and echo final empty string: $ cat mcal.sh cal | sed 's/_^H//g' | awk ' NR == 1 { print }; NR == 2 { print "Mo Tu We Th Fr Sa Su" } NR == 3 && NF < 7 { sub(/^.../, ""); sub(/ $/, ""); printf "%s", $0; } NR == 3 && NF == 7 { printf "%20s \n", $1; } NR > 3 { printf "%2s \n", $1; } NR > 3 || (NR == 3 && NF == 7) { for (i = 2; i <= NF; i++) printf "%2s ", $i; } ' echo '' $ sh mcal.sh June 2021 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 $ Fine, but it lacks highlighting of today because it was removed earlier by sed. To indicate it again I can save today's number in a variable and use it later in sed substitute to put the day in parenthesis: $ cat mcal.sh day=$(date | awk '{ print $3 }'); cal | sed 's/_^H//g' | awk ' NR == 1 { print }; NR == 2 { print "Mo Tu We Th Fr Sa Su" } NR == 3 && NF < 7 { sub(/^.../, ""); sub(/ $/, ""); printf "%s", $0; } NR == 3 && NF == 7 { printf "%20s \n", $1; } NR > 3 { printf "%2s \n", $1; } NR > 3 || (NR == 3 && NF == 7) { for (i = 2; i <= NF; i++) printf "%2s ", $i; } ' | sed "s/^/ /; s/ $day /($day)/"; echo '' $ sh mcal.sh June 2021 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 (9)10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 $ I've added additional space to beginning of lines to prevent offset of line due to putting Monday in parenthesis.