'Comparing two files with respective fields and output required in a specific format

I am comparing two files

food1.txt file and compares food2.txt file, like this

# cat food1.txt 
pizza=1ea
chicken=5ea
tooboo=4ea
orange=2ea
# cat food2.txt 
pizza=2ea
chicken=5ea
grape=3ea
tooboo=4ea
melon=1ea
  • my work...
FOOD1=`cat ./food1.txt`
FOOD2=`cat ./food2.txt`

echo "$FOOD1" | while read ACCOUNT
do
grep -w $ACCOUNT ./food2.txt  >/dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "-----[  OK  ] : $ACCOUNT"
else
echo "-----[ WARN ] : $ACCOUNT"
fi
done 
  • output.. but i don't like it
-----[ WARN ] : pizza=1ea
-----[  OK  ] : chicken=5ea
-----[  OK  ] : tooboo=4ea
-----[ WARN ] : orange=2ea

I want to print the comparison target together

  • I want output, like this
food2.txt                   food1.txt
pizza=2ea   : [ NotMatch ] : pizza=1ea
            : [    OK    ] : chicken=5ea
            : [    OK    ] : tooboo=4ea
            : [ NotExist ] : orange=2ea
grape=3ea   : [ NotExist ] :
melon=1ea   : [ NotExist ] :

Is it possible? please help me.



Solution 1:[1]

As bash is tagged, here's a solution using associative arrays. The first while loop populates the array reading the first file. The second while loop iterates over the second file, checks whether keys and/or values match with entries in the array, and deletes them. Finally the for loop iterates over the remaining "unchecked" items in the array.

out() {
  if   [[      -z "$3" ]]; then l="$1"    m="                " r="$2"
  elif [[      -z "$2" ]]; then l="$3=$1" m=": [ NotExist ] :" r=""
  elif [[      -z "$1" ]]; then l=""      m=": [ NotExist ] :" r="$3=$2"
  elif [[ "$2" == "$1" ]]; then l=""      m=": [    OK    ] :" r="$3=$2"
  else                          l="$3=$1" m=": [ NotMatch ] :" r="$3=$2"; fi
  printf '%-10s %s %-10s\n' "$l" "$m" "$r"
}

f1=food1.txt
f2=food2.txt

out "$f2" "$f1"

declare -A f
while IFS== read -r k v; do f[$k]=$v; done < "$f2"

while IFS== read -r k v; do out "${f[$k]}" "$v" "$k"; unset f[$k]; done < "$f1"

for k in "${!f[@]}"; do out "${f[$k]}" "" "$k"; done
food2.txt                   food1.txt 
pizza=2ea  : [ NotMatch ] : pizza=1ea 
           : [    OK    ] : chicken=5ea
           : [    OK    ] : tooboo=4ea
           : [ NotExist ] : orange=2ea
grape=3ea  : [ NotExist ] :           
melon=1ea  : [ NotExist ] :

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 pmf