Skip to content

Instantly share code, notes, and snippets.

@RWJMurphy
Created February 4, 2013 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RWJMurphy/4704584 to your computer and use it in GitHub Desktop.
Save RWJMurphy/4704584 to your computer and use it in GitHub Desktop.
Like sort(1), only in Python, and capable of sorting by line length.
#!/usr/bin/env python
import argparse
import os
import random
import re
import string
import sys
def number_or_zero(x):
try:
return float(x)
except ValueError:
return 0.0
# reduce(lambda arg, func: func(arg), [arg] + funcs)
def apply_funcs(funcs, arg):
result = arg
for func in funcs:
result = func(result)
return result
def main(args):
status = os.EX_OK
lines = []
reverse = args.reverse
for input_file in args.FILE:
if input_file == "-":
input_file = sys.stdin
else:
input_file = open(input_file, 'r')
lines.extend(line.rstrip('\n') for line in input_file)
prefilters = []
if args.ignore_leading_blanks:
prefilters.append(lambda x: x.lstrip())
if args.dictionary_order:
prefilters.append(lambda x: re.sub(
'[^' + string.letters + string.whitespace + string.digits + ']+',
'',
x
))
if args.ignore_case:
prefilters.append(lambda x: x.upper())
if args.ignore_nonprinting:
prefilters.append(lambda x: re.sub(
'[^' + string.printable + ']+',
'',
x
))
comparison = lambda x: x
if args.length:
comparison = lambda x: len(x)
elif args.numeric_sort:
comparison = lambda x: number_or_zero(x)
if args.random_sort:
random.shuffle(lines)
else:
lines.sort(key=lambda line: comparison(apply_funcs(prefilters, line)), reverse=reverse)
print("\n".join(lines))
return status
if __name__ == "__main__":
exit_code = os.EX_OK
parser = argparse.ArgumentParser(
description="Sort lines of text",
usage="%(prog)s [OPTION]... [FILE]..."
)
comparison_args = parser.add_mutually_exclusive_group()
comparison_args.add_argument('-l', '--length', help="compare by the length of each line ", action="store_true")
comparison_args.add_argument('-n', '--numeric-sort', help="compare according to string numerical value", action="store_true")
comparison_args.add_argument('-R', '--random-sort', help="shuffle the input, rather than sorting", action="store_true")
parser.add_argument('-b', '--ignore-leading-blanks', help="ignore leading blanks", action="store_true")
parser.add_argument('-d', '--dictionary-order', help="consider only blanks and alphanumeric characters", action="store_true")
parser.add_argument('-f', '--ignore-case', help="fold lower case to upper case characters", action="store_true")
parser.add_argument('-r', '--reverse', help="reverse the result of comparisons", action="store_true")
parser.add_argument('-i', '--ignore-nonprinting', help="consider only printable characters", action="store_true")
parser.add_argument('-V', '--version', action='version', version='%(prog)s 0.2')
parser.add_argument('FILE', nargs="*", default=['-'], help="The files to be sorted. If unsupplied, or '-', reads from standard input.")
args = parser.parse_args()
try:
exit_code = main(args)
except KeyboardInterrupt:
pass
sys.exit(exit_code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment