From a1a94db67818bedde40e4022a1a3c4ffadda1b79 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sat, 7 Dec 2013 19:53:43 +0100 Subject: common-bytes.py: context support With the "-C" option, a number of columns can be included before skipping them. Bugfix: reset skip state to avoid eating chars at the beginning for the next line. Enhancement: ignore EPIPE. Also adjusted the middle threshold to 9 ("XX..N..XX"). --- common-bytes.py | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/common-bytes.py b/common-bytes.py index 2376fb6..362203e 100755 --- a/common-bytes.py +++ b/common-bytes.py @@ -105,24 +105,45 @@ def color_cells(lines, line_width, top_counts): # Find columns that can be skipped # common at begin: N..[other] (threshold: 5) # common at end: [other]..N (threshold: 5) -# common in middle: [other]..N..[other] (threshold: 7) -def mark_skippable(colormap, line_width): +# common in middle: [other]..N..[other] (threshold: 9) +def mark_skippable(colormap, line_width, context): skip_mask = [0] * line_width skip_cols = 0 threshold = 5 + is_right = True for col in reversed(range(0, line_width)): if colormap[0][col] == 0: # this column can maybe be skipped skip_cols += 1 - skip_mask[col] = -1 + # If on the right, then there is no context to show. Otherwise, + # reserve enough columns for the context. + if is_right or skip_cols > context: + skip_mask[col] = -1 else: # this column cannot be skipped + # For the middle, more context need to be available + if not is_right: + skip_cols -= 2 * context + else: + skip_cols -= context + # Insert skip marker if possible, otherwise ignore if skip_cols > threshold: - skip_mask[col + 1] = skip_cols + # Display these columns... + for i in range(1, context + 1): + skip_mask[col + i] = 0 + # ... and insert the skip count after the context + skip_mask[col + 1 + context] = skip_cols + # Must be the middle now. - threshold = 10 + is_right = False + threshold = 9 skip_cols = 0 + # at begin, are there any cells to skip? + # Keep context if there were differences on the right (i.e. if some columns + # on the right were not skipped, but shown) + if not is_right: + skip_cols -= context threshold = 5 if skip_cols > threshold: skip_mask[0] = skip_cols @@ -138,11 +159,11 @@ CELL_OUTLIER: "\033[1;31m", # red # Display input, coloring changes def display_changes(lines, line_width, colormap, skip_mask, enable_skip): - skipping = False for lineno, line in enumerate(lines): line_out = "" prev_color = CLEAR_COLOR line_color = colormap[lineno] + skipping = False for col in range(0, line_width): # skip common cells? if enable_skip: @@ -187,7 +208,7 @@ def main(args): colormap = color_cells(lines, line_width, top_counts) # Shorten lines by cutting out common stuff - skip_mask = mark_skippable(colormap, line_width) + skip_mask = mark_skippable(colormap, line_width, args.context) # Finally display the input, colored. display_changes(lines, line_width, colormap, skip_mask, args.enable_skip) @@ -198,6 +219,9 @@ if __name__ == "__main__": import argparse parser = argparse.ArgumentParser( description="Assume common lines, mark tiny differences") + parser.add_argument("-C", required=False, type=int, default=0, + dest="context", metavar="NUM", + help="Number of columns to keep as context") parser.add_argument("-c", required=False, type=int, default=0, dest="line_width", metavar="LENGTH", help="Truncate input lines to LENGTH (default 0, unlimited)") @@ -209,4 +233,8 @@ if __name__ == "__main__": help="Enable skipping common columns") parser.add_argument("files", nargs=argparse.REMAINDER) args = parser.parse_args() - sys.exit(main(args)) + try: + sys.exit(main(args)) + except BrokenPipeError: + # ignore EPIPE for pipes like: thisScript.py | head + pass -- cgit v1.2.1