Search code examples
diffaixcarriage-return

AIX diff -b broken?


I'm trying to compare files ignoring carriage returns - which diff -b on any other unix performs admirably. But on this AIX 5.3 box:

    tst1:tst2$ od -c testfile
0000000    t   h   i   s  \r  \n   f   i   l   e  \r  \n   h   a   s  \r
0000020   \n   c   a   r   r   i   a   g   e  \r  \n   r   e   t   u   r
0000040    n   s  \r  \n
0000044
tst1:tst2$ od -c testfile_nocr
0000000    t   h   i   s  \n   f   i   l   e  \n   h   a   s  \n   c   a
0000020    r   r   i   a   g   e  \n   r   e   t   u   r   n   s  \n
0000037
tst1:tst2$ diff -b testfile testfile_nocr
1,5c1,5
< this
< file
< has
< carriage
< returns
---
> this
> file
> has
> carriage
> returns
tst1:tst2$

Why so?


Solution

  • AIX 5.3 diff does not appear to consider \r as white space. See the following transcript:

    /home/pax: od -c file1
    0000000    h   e   l   l   o  \n   t   h   e   r   e  \n
    0000014
    
    /home/pax: od -c file2
    0000000    h   e   l   l   o  \r  \n   t   h   e   r   e  \r \n
    0000016
    
    /home/pax: od -c file3
    0000000    h   e   l   l   o      \n   t   h   e   r   e     \n
    0000016
    
    /home/pax: od -c file4
    0000000    h   e   l   l   o  \t  \n   t   h   e   r   e  \t \n
    0000016
    
    /home/pax: diff -b file1 file2
    1,2c1,2
    < hello
    < there
    ---
    > hello
    > there
    
    /home/pax: diff -b file1 file3
    <<No output>>
    
    /home/pax: diff -b file1 file4
    <<No output>>
    

    The manpage for diff is a little obtuse on the matter, stating that -b will "cause any amount of white space at the end of the line to be treated as a single newline character ..." but does not actually define what it considers to be white space.

    Based on the above transcript, I would gather that spaces and tabs are okay but carriage returns are not.

    One way to get around this will be to remove the carriage returns yourself with a script like:

    #!/usr/bin/ksh
    # crdiff: diffs two files after changing \r\n to \n in both.
    if [[ $# -ne 2 ]] ; then
        echo 'Usage: crdiff <file> <file2>'
        return 1
    fi
    perl -pne 's/\r$//' $1 >/tmp/xyzzy_$$_$1
    perl -pne 's/\r$//' $2 >/tmp/xyzzy_$$_$2
    diff -b /tmp/xyzzy_$$_$1 /tmp/xyzzy_$$_$2
    rc=$?
    rm -f /tmp/xyzzy_$$_$1 /tmp/xyzzy_$$_$2
    return $rc
    

    Alternatively, you could compile the GNU diff utility on your box and insert it into the path before /usr/bin - it appears to have no trouble with \r as white space. In fact, we do exactly that on our AIX4 boxes since diff there doesn't even pretend to support the -b option.