diff --git a/bin/tsvhead b/bin/tsvhead new file mode 120000 index 0000000..2d36d85 --- /dev/null +++ b/bin/tsvhead @@ -0,0 +1 @@ +../tsv/tsvhead \ No newline at end of file diff --git a/bin/tsvtail b/bin/tsvtail new file mode 120000 index 0000000..ae31ea4 --- /dev/null +++ b/bin/tsvtail @@ -0,0 +1 @@ +../tsv/tsvtail \ No newline at end of file diff --git a/tsv/tsvhead b/tsv/tsvhead new file mode 100755 index 0000000..c40df35 --- /dev/null +++ b/tsv/tsvhead @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# +# Copyright 2015 Ville Rantanen +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +'''simple head for tsv/csv files.''' + +__author__ = "Ville Rantanen " + +__version__ = "0.1" + +import sys,os,argparse +from argparse import ArgumentParser + +def setup_options(): + ''' Create command line options ''' + usage=''' +Simple implementation of head that keeps the header row. + +''' + + parser=ArgumentParser(description=usage, + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog="\n".join(["Version: "+__version__,__author__])) + common_group=parser.add_argument_group('common', 'Common options') + common_group.add_argument("-v","--version",action="version",version=__version__) + common_group.add_argument("-n",type=int,dest="lines",default=False, + help="Lines to show from beginning of file. Negative value to show lines but the number. Default: 10") + parser.add_argument("file",type=str, nargs='*', + help="File(s) to be headed") + opts=parser.parse_args() + if not opts.lines: + int(opts.file[0]) + opts.lines=int(opts.file.pop(0)) + if not opts.lines: + opts.lines=10 + return opts + +def behead(fileob,opts): + + header=fileob.readline() + sys.stdout.write(header) + if opts.lines>=0: + head_ordinary(fileob, opts.lines) + else: + head_allbutlast(fileob, opts.lines) + +def head_ordinary(fileob, lines): + for i,row in enumerate(fileob): + if i>lines-1: + break + sys.stdout.write(row) + +def head_allbutlast(fileob, lines): + lines=-lines + buf=[] + for row in fileob: + buf.append(row) + if len(buf)>lines: + sys.stdout.write(buf.pop(0)) + +def main(): + opts=setup_options() + try: + if (not sys.stdin.isatty()): + behead(sys.stdin, opts) + for fi in opts.file: + behead(open(fi,'r'), opts) + except IOError as (n,e): + if n==32: + pass + else: + import traceback + print traceback.format_exc() + +if __name__ == "__main__": + main() diff --git a/tsv/tsvtail b/tsv/tsvtail new file mode 100755 index 0000000..7c2f478 --- /dev/null +++ b/tsv/tsvtail @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# +# Copyright 2015 Ville Rantanen +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +'''simple tail for tsv/csv files.''' + +__author__ = "Ville Rantanen " + +__version__ = "0.1" + +import sys,os,argparse +from argparse import ArgumentParser + +def setup_options(): + ''' Create command line options ''' + usage=''' +simple implementation of tail, keeping the header row + +''' + + parser=ArgumentParser(description=usage, + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog="\n".join(["Version: "+__version__,__author__])) + common_group=parser.add_argument_group('common', 'Common options') + common_group.add_argument("-v","--version",action="version",version=__version__) + common_group.add_argument("-n",type=str,dest="lines",default=False, + help="Lines to show from end of file. +K to start output from the Kth. Default: 10") + parser.add_argument("file",type=str, nargs='*', + help="File(s) to be headed") + opts=parser.parse_args() + if not opts.lines: + int(opts.file[0]) + opts.lines=opts.file.pop(0) + if not opts.lines: + opts.lines="10" + if opts.lines.startswith("+"): + opts.lines=-int(opts.lines) + else: + opts.lines=int(opts.lines) + return opts + +def tail(fileob,opts): + + header=fileob.readline() + sys.stdout.write(header) + if opts.lines>=0: + tail_ordinary(fileob, opts.lines) + else: + tail_allbutfirst(fileob, -opts.lines) + +def tail_allbutfirst(fileob, lines): + for i,row in enumerate(fileob): + if ilines: + buf.pop(0) + [sys.stdout.write(l) for l in buf] + +def main(): + opts=setup_options() + try: + if (not sys.stdin.isatty()): + tail(sys.stdin, opts) + for fi in opts.file: + tail(open(fi,'r'), opts) + except IOError as (n,e): + if n==32: + pass + else: + import traceback + print traceback.format_exc() + +if __name__ == "__main__": + main()