How can I get the unix command diff show only added and deleted lines? If diff can't do it, what tool can?
4 Answers
I'm not sure this is possible as it will be hard to differentiate between changed, added and deleted lines.
Consider this file:
start
old
old
old
end
We edit it so it looks like this:
start
old
old but now new
new
new
end
If we diff
it we get this output:
< old
< old
---
> old but now new
> new
> new
This is straightforward to generate. But if you ask diff
to only print added and deleted line I think it becomes a matter of opinion which lines have been added and deleted and which have been changed. For example, did I delete the the last line that said old
and replace it with a line that said new
or did I edit it?
-
1(+1) Agree in principle, but there should be a way to get what diff thinks are the added and deleted lines. To put it another way, show the ouput of
sdiff file1 file2
without the lines that have entries on both sides. If you treat all changed lines as deleted and added lines, you basically get the output ofcomm -3 file1 file2
– user4358Commented Sep 25, 2009 at 14:38
Does diff -u0
do what you want?
-
-
2
I had the same question. This function was my solution to obtain the maximum change line number (i.e. changes start with the letter '+'). After which I then loop through the diff file again line by line and do not send to the line processor until this triggers the line to process:
#====================================================================
proc_diff_file() # processes a diff file
#====================================================================
# Arg_1 = Diff File Name
# Arg_2 = New File Name - the one with the new lines
{
NEW_FILE=$1
A_FILE=$2
if [ -f "$A_FILE" ]; then
echo "processing diff $A_FILE"
pre_process_diff $A_FILE
# Set loop separator to end of line
ndx=0
BAKIFS=$IFS
IFS=$(echo -en "\n\b")
exec 3<&0
exec 0<$A_FILE
while read line
do
ndx=$(expr $ndx + 1)
# use $line variable to process line in processLine() function
if [ $ndx > $max_ndx ]; then
proc_age $line
fi
done
exec 0<&3
# restore $IFS which was used to determine what the field separators are
IFS=$BAKIFS
# cleanup $NEW_FILE
echo "processing diff $A_FILE done"
fi
}
Here is the function:
#====================================================================
pre_process_diff() # pre-processes a diff file for last changed line
# sets a variable named $max_ndx
#====================================================================
# Arg_1 = Diff File Name
{
A_FILE=$1
max_ndx=
# collect last line number of diff +
# all lines following are new data
`grep -n "^[+]" $A_FILE | gawk '-F:' '{ print $1 }' >tmp`
# Set loop separator to end of line
# read through to the last line number
BAKIFS=$IFS
IFS=$(echo -en "\n\b")
exec 3<&0
exec 0<tmp
while read last_line
do
max_ndx=$last_line
done
exec 0<&3
# restore $IFS which was used to determine what the field separators are
IFS=$BAKIFS
echo "pre-processing diff $A_FILE done max_ndx=$max_ndx"
}
Steve
-
Install GNU diff, and use that. AIX' tools are severely outdated.– vonbrandCommented Oct 9, 2015 at 21:57
I find it simplest to use grep:
Added lines:
grep -xvFf filea.txt fileb.txt
Removed lines:
grep -xvFf fileb.txt filea.txt
-x
: match whole lines
-v
: lines NOT matching the pattern(s)
-F
: treat patterns as fixed strings, not regular expressions
-f <otherfile>
: read the list of patterns from a file
-
this works great for comparison with current and original package install lists. Makes it easy to see what has been installed/removed since initial configuration (as least for Arch)– DKeblerCommented Feb 13 at 20:40