| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  | """ndiff [-q] file1 file2
 | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  |     or | 
					
						
							|  |  |  | ndiff (-r1 | -r2) < ndiff_output > file1_or_file2 | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Print a human-friendly file difference report to stdout.  Both inter- | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  | and intra-line differences are noted.  In the second form, recreate file1 | 
					
						
							|  |  |  | (-r1) or file2 (-r2) on stdout, from an ndiff report on stdin. | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  | In the first form, if -q ("quiet") is not specified, the first two lines | 
					
						
							|  |  |  | of output are | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | -: file1 | 
					
						
							|  |  |  | +: file2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Each remaining line begins with a two-letter code: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     "- "    line unique to file1 | 
					
						
							|  |  |  |     "+ "    line unique to file2 | 
					
						
							|  |  |  |     "  "    line common to both files | 
					
						
							|  |  |  |     "? "    line not present in either input file | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Lines beginning with "? " attempt to guide the eye to intraline | 
					
						
							| 
									
										
										
										
											2000-11-01 02:51:27 +00:00
										 |  |  | differences, and were not present in either input file.  These lines can be | 
					
						
							|  |  |  | confusing if the source files contain tab characters. | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The first file can be recovered by retaining only lines that begin with | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  | "  " or "- ", and deleting those 2-character prefixes; use ndiff with -r1. | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-11-01 02:51:27 +00:00
										 |  |  | The second file can be recovered similarly, but by retaining only "  " and | 
					
						
							|  |  |  | "+ " lines; use ndiff with -r2; or, on Unix, the second file can be | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  | recovered by piping the output through | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  |     sed -n '/^[+ ] /s/^..//p' | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-12 22:25:01 +00:00
										 |  |  | __version__ = 1, 7, 0 | 
					
						
							| 
									
										
										
										
											1998-05-06 17:43:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-12 22:25:01 +00:00
										 |  |  | import difflib, sys | 
					
						
							| 
									
										
										
										
											2000-11-01 02:51:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  | def fail(msg): | 
					
						
							|  |  |  |     out = sys.stderr.write | 
					
						
							|  |  |  |     out(msg + "\n\n") | 
					
						
							|  |  |  |     out(__doc__) | 
					
						
							|  |  |  |     return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-05-06 17:43:30 +00:00
										 |  |  | # open a file & return the file object; gripe and return 0 if it | 
					
						
							|  |  |  | # couldn't be opened | 
					
						
							|  |  |  | def fopen(fname): | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2013-11-23 22:12:06 +02:00
										 |  |  |         return open(fname) | 
					
						
							| 
									
										
										
										
											2007-01-10 16:19:56 +00:00
										 |  |  |     except IOError as detail: | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  |         return fail("couldn't open " + fname + ": " + str(detail)) | 
					
						
							| 
									
										
										
										
											1998-05-06 17:43:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # open two files & spray the diff to stdout; return false iff a problem | 
					
						
							|  |  |  | def fcompare(f1name, f2name): | 
					
						
							|  |  |  |     f1 = fopen(f1name) | 
					
						
							|  |  |  |     f2 = fopen(f2name) | 
					
						
							|  |  |  |     if not f1 or not f2: | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     a = f1.readlines(); f1.close() | 
					
						
							|  |  |  |     b = f2.readlines(); f2.close() | 
					
						
							| 
									
										
										
										
											2001-09-22 21:30:22 +00:00
										 |  |  |     for line in difflib.ndiff(a, b): | 
					
						
							| 
									
										
										
										
											2007-08-03 17:06:41 +00:00
										 |  |  |         print(line, end=' ') | 
					
						
							| 
									
										
										
										
											1998-05-06 17:43:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  | # crack args (sys.argv[1:] is normal) & compare; | 
					
						
							|  |  |  | # return false iff a problem | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def main(args): | 
					
						
							|  |  |  |     import getopt | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  |         opts, args = getopt.getopt(args, "qr:") | 
					
						
							| 
									
										
										
										
											2007-01-10 16:19:56 +00:00
										 |  |  |     except getopt.error as detail: | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  |         return fail(str(detail)) | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  |     noisy = 1 | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  |     qseen = rseen = 0 | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  |     for opt, val in opts: | 
					
						
							|  |  |  |         if opt == "-q": | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  |             qseen = 1 | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  |             noisy = 0 | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  |         elif opt == "-r": | 
					
						
							|  |  |  |             rseen = 1 | 
					
						
							|  |  |  |             whichfile = val | 
					
						
							|  |  |  |     if qseen and rseen: | 
					
						
							|  |  |  |         return fail("can't specify both -q and -r") | 
					
						
							|  |  |  |     if rseen: | 
					
						
							|  |  |  |         if args: | 
					
						
							|  |  |  |             return fail("no args allowed with -r option") | 
					
						
							| 
									
										
										
										
											2003-05-13 17:56:07 +00:00
										 |  |  |         if whichfile in ("1", "2"): | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  |             restore(whichfile) | 
					
						
							|  |  |  |             return 1 | 
					
						
							|  |  |  |         return fail("-r value must be 1 or 2") | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  |     if len(args) != 2: | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  |         return fail("need 2 filename args") | 
					
						
							| 
									
										
										
										
											1999-03-27 13:34:01 +00:00
										 |  |  |     f1name, f2name = args | 
					
						
							|  |  |  |     if noisy: | 
					
						
							| 
									
										
										
										
											2007-08-03 17:06:41 +00:00
										 |  |  |         print('-:', f1name) | 
					
						
							|  |  |  |         print('+:', f2name) | 
					
						
							| 
									
										
										
										
											1998-05-06 17:43:30 +00:00
										 |  |  |     return fcompare(f1name, f2name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-12 22:25:01 +00:00
										 |  |  | # read ndiff output from stdin, and print file1 (which=='1') or | 
					
						
							|  |  |  | # file2 (which=='2') to stdout | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  | def restore(which): | 
					
						
							| 
									
										
										
										
											2001-08-12 22:25:01 +00:00
										 |  |  |     restored = difflib.restore(sys.stdin.readlines(), which) | 
					
						
							| 
									
										
										
										
											2001-09-23 04:06:05 +00:00
										 |  |  |     sys.stdout.writelines(restored) | 
					
						
							| 
									
										
										
										
											1999-03-28 17:55:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-05-06 17:43:30 +00:00
										 |  |  | if __name__ == '__main__': | 
					
						
							| 
									
										
										
										
											2022-10-07 19:57:48 +02:00
										 |  |  |     main(sys.argv[1:]) |