3

I am looking from something which gives me an output of comm -3 on two sorted outputs (line-by-line comparison, only additional/missing lines from either side) but which looks more like the output from diff -y, e.g. in that it uses the whole width.

file1:

bar/a
bar/feugiat
bar/libero
bar/mauris
bar/scelerisque
bar/urna
foo/blandit
foo/elementum
foo/feugiat
foo/laoreet
foo/luctus
foo/non
foo/pellentesque
foo/pulvinar
foo/rutrum
foo/sed
foo/ut
foo/vivamus

file2:

bar/a
bar/molestie
bar/quam
bar/risus
bar/tristique
foo/blandit
foo/elementum
foo/feugiat
foo/ligula
foo/massa
foo/mauris
foo/metus
foo/pellentesque
foo/pulvinar
foo/ut

Output from comm -3 file1 file2:

bar/feugiat
bar/libero
bar/mauris
        bar/molestie
        bar/quam
        bar/risus
bar/scelerisque
        bar/tristique
bar/urna
foo/laoreet
        foo/ligula
foo/luctus
        foo/massa
        foo/mauris
        foo/metus
foo/non
foo/rutrum
foo/sed
foo/vivamus

Output from diff -y --suppress-common-lines file1 file2 (GNU), it depends on the screen width:

bar/feugiat                                                   | bar/molestie
bar/libero                                                    | bar/quam
bar/mauris                                                    | bar/risus
bar/scelerisque                                               | bar/tristique
bar/urna                                                      <
foo/laoreet                                                   | foo/ligula
foo/luctus                                                    | foo/massa
foo/non                                                       | foo/mauris
                                                              > foo/metus
foo/rutrum                                                    / foo/ut
foo/sed                                                       <
foo/ut                                                        <
foo/vivamus                                                   <

Possible output I would wish for:

bar/feugiat                                                   <
bar/libero                                                    <
bar/mauris                                                    <
                                                              > bar/molestie
                                                              > bar/quam
                                                              > bar/risus
bar/scelerisque                                               <
                                                              > bar/tristique
bar/urna                                                      <
foo/laoreet                                                   <
                                                              > foo/ligula
foo/luctus                                                    <
                                                              > foo/massa
                                                              > foo/mauris
                                                              > foo/metus
foo/non                                                       <
foo/rutrum                                                    <
foo/sed                                                       <
foo/vivamus                                                   <

Without the arrows would be OK as well, just the screen width should be used better:

bar/feugiat
bar/libero
bar/mauris
                                                                bar/molestie
                                                                bar/quam
                                                                bar/risus
bar/scelerisque
                                                                bar/tristique
bar/urna
foo/laoreet
                                                                foo/ligula
foo/luctus
                                                                foo/massa
                                                                foo/mauris
                                                                foo/metus
foo/non
foo/rutrum
foo/sed
foo/vivamus
5

You could pipe to:

expand -t "$((${COLUMNS:-$(tput cols)} / 2))"

Or for the angle brackets:

awk -v cols="${COLUMNS:-$(tput cols)}" '
  BEGIN {width = cols/2-1; space = sprintf("%*s", width, "")}
  /^\t/ {print space ">", substr($0, 2); next}
  {printf "%-*s<\n", width, $0}'

If your tput doesn't output the number of columns, you could try parsing the output of stty size or stty -a. Or use zsh -c 'echo $COLUMNS' (also works with mksh). There's no standard/portable way to get that information.

If the input files contain multi-byte or double-width characters, YMMV. Depending on the expand/awk implementation alignment may be off.

That also assumes that the input files have no line that start with a Tab character. If that can't be guaranteed, the GNU implementation of comm has a --output-delimiter which you could use to specify a unique string. Or you could implement the comm functionality in awk which shouldn't be too complicated.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.