Skip to content
Advertisement

How can i display the first five lines that differ between 2 files, in a shell script?

I ve tried using 2 arrays to compare the 2 files, but i m a rookie and i don’t know how to do it:

vec_fis_1=`cat fisier.txt`
vec_fis_2=`cat fisier1.txt`
echo $vec_fis_2
echo $vec_fis_1
for i in ${vec_fis_1[@]}
do
        for j in ${vec_fis_2[@]}
        do
                if ( "$i" == "$j" )
                then
                        echo $i
                        echo $j
                fi
        done
done

Advertisement

Answer

Do not use backticks `. Use $(..) instead.

So instead of if ( "$i" == "$j" ) do if [ "$i" != "$j" ].

vec_fis_1 and vec_fis_2 are not arrays – ${vec_fis_1[@]} is just same as $vec_fis_1.

To read a file into an array, use readarray.

To iterate over lines in file use a while read loop, see bashfaq how to read a file line by line.

while IFS= read -r l1; do
     while IFS= read -r l2; do
         if [ "$l1" != "$l2" ]; then
            printf "%sn" "$l1"
            printf "%sn" "$l2"
         fi
     done < fisier1.txt
done < fisier.txt

i only need the differences between lines with the same “line index”

So read from both files at the same time.

while IFS= read -r -u3 l1 && 
         IFS= read -r -u4 l2; do
    if [ "$l1" != "$l2" ]; then
        printf "%sn" "$l1"
        printf "%sn" "$l2"
     fi
done 3< fisier.txt 4< fisier1.txt

You could handle a different count of lines too. I have this (rather verbose) idea:

while true; do

    IFS= read -r -u3 l1
    l1valid=$?
    IFS= read -r -u4 l2
    l2valid=$?
    if ((l1valid != 0 || l2valid != 0)); then
        if ((l1valid != 0 && l2valid == 0)); then
           echo "file1 is longer then file2"
        elif ((l1valid == 0 && l2valid != 0)); then
           echo "file1 is shorter then file2"
        fi # l1valid != 0 && l2valid != 0 - all fine
        break;
    fi

    if [ "$l1" != "$l2" ]; then
        printf "%sn" "$l1"
        printf "%sn" "$l2"
     fi

done 3< fisier.txt 4< fisier1.txt

or like:

while
    IFS= read -r -u3 l1
    l1valid=$?
    IFS= read -r -u4 l2
    l2valid=$?
    if ((l1valid != 0 && l2valid == 0)); then
       echo "file1 is longer then file2"
    elif ((l1valid == 0 && l2valid != 0)); then
       echo "file1 is shorter then file2"
    fi
    (( l1valid == 0 && l2valid == 0 ))
do
    if [ "$l1" != "$l2" ]; then
        printf "%sn" "$l1"
        printf "%sn" "$l2"
     fi
done 3< fisier.txt 4< fisier1.txt

Note that bash loops are very slow, it will be magnitudes faster with awk:

awk -vother="fisier1.txt" '{ t=$0; getline < (other); if (t != $0) print $0 RS t }' fisier.txt
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement