#!/usr/bin/env bash
set -euo pipefail
if [[ $# -ne 2 ]]; then
echo "Usage: $0 <file-A> <file-B>" >&2
exit 1
fi
FILE_A="$1"
FILE_B="$2"
if [[ ! -f "$FILE_A" ]]; then
echo "Error: file does not exist: $FILE_A" >&2
exit 1
fi
if [[ ! -f "$FILE_B" ]]; then
echo "Error: file does not exist: $FILE_B" >&2
exit 1
fi
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT
SORTED_A="$TMPDIR/a.sorted"
SORTED_B="$TMPDIR/b.sorted"
ONLY_A="$TMPDIR/only-a"
ONLY_B="$TMPDIR/only-b"
normalize_file() {
local input="$1"
local output="$2"
awk '
{
sub(/\r$/, "")
gsub(/^[[:space:]]+/, "")
gsub(/[[:space:]]+$/, "")
if ($0 == "")
next
sub(/^\./, "")
if ($0 !~ /^[0-9]+(\.[0-9]+)*$/) {
printf "Warning: ignoring invalid OID in %s: %s\n",
FILENAME, $0 > "/dev/stderr"
next
}
print
}
' "$input" |
LC_ALL=C sort -u > "$output"
}
normalize_file "$FILE_A" "$SORTED_A"
normalize_file "$FILE_B" "$SORTED_B"
LC_ALL=C comm -23 "$SORTED_A" "$SORTED_B" > "$ONLY_A"
LC_ALL=C comm -13 "$SORTED_A" "$SORTED_B" > "$ONLY_B"
COUNT_A="$(wc -l < "$ONLY_A")"
COUNT_B="$(wc -l < "$ONLY_B")"
echo "========================================"
echo "PRESENT IN A ($FILE_A), ABSENT IN B ($FILE_B)"
echo "========================================"
echo
if [[ -s "$ONLY_A" ]]; then
cat "$ONLY_A"
else
echo "(none)"
fi
echo
echo "========================================"
echo "PRESENT IN B ($FILE_B), ABSENT IN A ($FILE_A)"
echo "========================================"
echo
if [[ -s "$ONLY_B" ]]; then
cat "$ONLY_B"
else
echo "(none)"
fi
echo
echo "========================================"
echo "SUMMARY"
echo "========================================"
echo
echo "A ($FILE_A) -> B ($FILE_B) missing: $COUNT_A"
echo "B ($FILE_B) -> A ($FILE_A) missing: $COUNT_B"
if [[ "$COUNT_A" -eq 0 && "$COUNT_B" -eq 0 ]]; then
echo
echo "A ($FILE_A) and B ($FILE_B) contain the same set of OIDs."
fi