How can I diff two files and report the section the diff occurs in?
I h开发者_运维技巧ave two text files with several sections in them. Each section has has a header with the section name (grep can extract all the section names without extracting anything else from the file). How can I report the differences between the two files AND report the section that the difference occurs in? I would also need to be able to report added/missing sections. Ideally, identical sections would not be mentioned in the report at all.
Use diff
's --show-function-line
parameter :
diff -U 0 --show-function-line='^HEAD ' old-file new-file
It won't report the correct section if it apears only in the output file (for example if you added a new section at the end of the file, the added lines will appear as being in the last section of the old file).
The following script might help, though it's far from being a one-liner. It will print :
- sections from the old file that have deleted lines, prefixed with
" -"
- sections from the new file that have inserted lines, prefixed with
" +"
- deleted lines (including deleted section headers), prefixed with
"+"
- inserted lines (including new section headers), prefixed with
"-"
Here is the script :
#!/bin/bash
# Usage : ./script old-file new-file
diff \
--new-line-format='+%dn'$'\n' \
--old-line-format='-%dn'$'\n' \
--unchanged-line-format='' \
$1 \
$2 \
| \
(
lnumOld=0;
lnumNew=0;
header='NO HEADER'
printheader=1
while read lprint; do
if [ "$((lprint))" -gt 0 ]; then
sep='+'
while [ $lnumNew -lt $lprint ]; do
read line <&4
if [ "${line#HEAD }" != "$line" ]; then
header="$sep$line"
printheader=1
fi
((lnumNew++));
done
else
sep='-'
while [ $lnumOld -lt $((-1*$lprint)) ]; do
read line <&3
if [ "${line#HEAD }" != "$line" ]; then
header="$sep$line"
printheader=1
fi
((lnumOld++));
done
fi
if [ $printheader = 1 ]; then
echo " $header"
printheader=0
fi
echo "$sep$line";
done) 3<"$1" 4<"$2"
If you introduce an artificial change in the headers, that will force them to show up in the diff. Not exactly what you want, but maybe that will give you an idea.
Assuming your regex for finding headers is ^HEAD
:
sed -e 's/^HEAD/>HEAD/' file1.txt | diff -u - file2.txt
Edit: If you want the resulting diff to be a real diff, you can use sed
to remove the HEAD difference lines.
sed -e 's/^HEAD/>HEAD/' file1.txt | diff -u - file2.txt | sed -e 's/^->HEAD/ HEAD/; /^+HEAD/D'
精彩评论