oneliner


Nameoneliner JSON
Version 0.3.1 PyPI version JSON
download
home_page
Summarypractical python one-liners
upload_time2024-02-18 17:47:15
maintainer
docs_urlNone
author
requires_python>=3.6
licenseCopyright (c) 2012-2024 Georgi Valkov. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GEORGI VALKOV BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
keywords oneliner one-liner
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Python Oneliner

This module improves Python\'s usefulness as a tool for writing shell
one-liners. A brief usage example:

``` bash
# show line numbers
python -m oneliner -ne '"%5d: %s" % (NR, _)' < input.txt

# convert unix timestamp to something more human readable
date +%s | pyl -j ' => ' -line '_, datetime.datetime.fromtimestamp(int(_))'
# 1355256353 => 2012-12-11 22:05:53

# triple space a file
pyl -ne 'line + "\n"*2' < input.txt

# double space only non-blank lines:
pyl -ne '_ if re.match("^$", _) else _+"\n"' input.txt
```

# Why?

Python is a wonderful general purpose scripting language with a great
breadth of excellent libraries. While the simplicity of its syntax is
often cited as a major strong point, I believe that the negative
attitude towards any kind of *syntax magic* has prevented Python from
becoming a useful tool for writing shell one-liners. When stacked
against the likes of Ruby and Perl, Python is ill-equipped to be a part
of a shell pipeline. Writing one-liners is possible, but their verbosity
makes them impractical. This may be attributed to the following factors:

1)  Lack of a *read-print-loop* command line option. Ruby and Perl
    provide the `-n` and `-p` switches that makes them assume the
    following loop around code:

        for line in sys.stdin:
            <code>
            if '-p' in options:
                sys.stdout.write(line)

2)  No *syntax magic* and no *special variables*. Ruby and Perl provide
    a multitude of cryptic, yet useful variables such as:

        $_   last input line
        $.   current input line number
        $~   the match object returned by the last successful pattern match
        $&   the string matched by last successful pattern match
        $3   the string matched by the 3rd group of the last successful pattern match
        $*   sys.argv
        $>   sys.stdout (default output file)
        $<   sys.stdint (default input file)
        $;   input field separator (default value to str.split())
        $/   record separator (os.linesep)
        $$   os.getpid()

    Please refer to [English.rb] and [English.pm] for more information.

3)  Lack of a flexible command line import mechanism. For example, Perl
    has the `-M` options:

        perl -MDigest::MD5=md5_hex  => from Digest::MD5 import md5_hex
        perl -MDigest::MD5          => import Digest::MD5

    While the CPython interpreter has the `-m` switch, it is not
    suitable for the task at hand. For example, the following one-liner
    will run [random\'s] test suite, instead of printing a random
    number:

        python -m random -c "print(random.randint(10))"

All these points add up to the verbosity of Python one-liners. The
following example demonstrates this:

``` bash
# convert a date to a unix timestamp (using strptime)
ruby -rdate -pe '$_=Date.strptime($_, "%Y-%m-%d").strftime("%s")'
perl -MTime::Piece -pe '$_=Time::Piece->strptime($_, "%Y-%m-%d\n")->epoch()'
python -c 'import sys,datetime; [sys.stdout.write(datetime.datetime.strptime("%Y-%m-%d", i).strftime("%s") for i in sys.stdin]'
```

But why would anyone want to write one-liners in Python, given these
shortcomings and the available alternatives? I believe that when doing
interactive work on the shell, the first solution that comes to mind is
usually good enough. If that solution is a Python one, why not use it?

# How?

Python comes with all the building blocks for implementing a practical
method of writing one-liners. This module tries to address the issues
outlined above. The command line interface is kept as close as that of
Ruby and Perl as reasonable.

1)  To help with the processing of input and output, *oneliner* provides
    the the `-n`, `-p` and `-l` command line switches.

    -   `-n`: assume the following loop around expressions or statements
        (the distinction will be clarified later):

            for line in sys.stdin:
                ...

    -   `-p`: like `-n`, but write the value of `line` to stdout at the
        end of each iteration:

            for line in sys.stdin:
                ...
                sys.stdout.write(line)

    -   `-l`: automatic line-ending processing. Roughly equivalent to:

            for line in sys.stdin:
                line = line.strip(os.linesep)
                ...
                sys.stdout.write(line)
                sys.stdout.write(os.linesep)

2)  Makes the following variables available in the local namespace of
    each one-liner:

    -   `line`, `L`, `_`: The current input line. Unless the `-l` switch
        is given, the line separatator will be a part of this string.

    -   `words`, `W`: Corresponds to the value of
        `re.split(delimiter, line)` where delimiter is the value of the
        `-d` option. Defaults to `\s+`.

        The `words` list will return an empty string instead of throwing
        an `IndexError` when a non-existent item is referenced. This
        behavior is similar to that of arrays in Ruby and field
        variables in Awk.

    -   `NR`: Current input line number.

    -   `FN`: Current input file name. If oneliner is processing input
        from stdin `FN` will be equal to `<stdin>`, otherwise it
        corresponds to the current input file given on the command line.
        For example:

            echo example | python -m oneliner -ne '"%s:%s\t %s" % (FN, NR, L)'
            => <stdin>:1     example

            python -m oneliner -ne '"%s:%s\t %s" % (FN, NR, L)' example.txt
            => example1.txt:1     line 1

3)  Provide the `-m` and `-M` options and a mini-language for specifying
    imports. This is best illustrated by an example:

        -m os,sys,re,pickle       => import os, sys, re, pickle
        -m os -m sys -m re        => import os, sys, re
        -m os sys re pickle       => import os, sys, re, pickle
        -m os.path.[*]            => from os.path import *
        -m os.path.[join,exists]  => from os.path import join, exists
        -m subprocess=sub         => import subprocess as sub
        -m datetime.[datetime=dt] => from datetime import datetime as dt
        -M os.path                => from os.path import *

# Installing

The latest stable version of *python-oneliner* is available on pypi and
may be installed with pip.

``` bash
$ python -m pip install oneliner
```

Alternatively, you may simply put the [oneline.py] file anywhere in
[sys.path]{.title-ref}.

# Todo

-   Support one-liners that don\'t deal with input/output only. If `-n`
    or `-p` are not given, *python-oneliner* should behave mostly like
    `python -c` does.
-   Persistent variables in statement one-liners.
-   The result of an expression one-liner is always written to stdout
    (even if `-n`).
-   Define the behaviour of multiple expression/statements specified on
    the command line.
-   Some means of emulating `BEGIN` and `END` (perhaps a `-b` and `-d`
    flag?)
-   Add more examples.

# Similar Projects

-   [Pyp]
-   [Pyle]
-   [Funcpy]
-   [Red]
-   [Pyfil]

# License

*Python-oneliner* is released under the terms of the [Revised BSD
License].

  [English.rb]: https://github.com/ruby/ruby/blob/trunk/lib/English.rb
  [English.pm]: http://cpansearch.perl.org/src/GBARR/perl5.005_03/lib/English.pm
  [random\'s]: http://hg.python.org/cpython/file/16b1fde2275c/Lib/random.py#l728
  [oneline.py]: https://raw.githubusercontent.com/gvalkov/python-oneliner/master/oneliner.py
  [Pyp]: http://code.google.com/p/pyp/
  [Pyle]: https://github.com/aljungberg/pyle
  [Funcpy]: http://www.pixelbeat.org/scripts/funcpy
  [Red]: https://bitbucket.org/johannestaas/red
  [Pyfil]: https://github.com/ninjaaron/pyfil
  [Revised BSD License]: https://raw.github.com/gvalkov/python-oneliner/master/LICENSE

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "oneliner",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "oneliner,one-liner",
    "author": "",
    "author_email": "Georgi Valkov <georgi.t.valkov@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/4f/be/3a1f7284b5bc64d8f6c63db6a60a069f6aaff33785cd603792fabfad5f73/oneliner-0.3.1.tar.gz",
    "platform": null,
    "description": "# Python Oneliner\n\nThis module improves Python\\'s usefulness as a tool for writing shell\none-liners. A brief usage example:\n\n``` bash\n# show line numbers\npython -m oneliner -ne '\"%5d: %s\" % (NR, _)' < input.txt\n\n# convert unix timestamp to something more human readable\ndate +%s | pyl -j ' => ' -line '_, datetime.datetime.fromtimestamp(int(_))'\n# 1355256353 => 2012-12-11 22:05:53\n\n# triple space a file\npyl -ne 'line + \"\\n\"*2' < input.txt\n\n# double space only non-blank lines:\npyl -ne '_ if re.match(\"^$\", _) else _+\"\\n\"' input.txt\n```\n\n# Why?\n\nPython is a wonderful general purpose scripting language with a great\nbreadth of excellent libraries. While the simplicity of its syntax is\noften cited as a major strong point, I believe that the negative\nattitude towards any kind of *syntax magic* has prevented Python from\nbecoming a useful tool for writing shell one-liners. When stacked\nagainst the likes of Ruby and Perl, Python is ill-equipped to be a part\nof a shell pipeline. Writing one-liners is possible, but their verbosity\nmakes them impractical. This may be attributed to the following factors:\n\n1)  Lack of a *read-print-loop* command line option. Ruby and Perl\n    provide the `-n` and `-p` switches that makes them assume the\n    following loop around code:\n\n        for line in sys.stdin:\n            <code>\n            if '-p' in options:\n                sys.stdout.write(line)\n\n2)  No *syntax magic* and no *special variables*. Ruby and Perl provide\n    a multitude of cryptic, yet useful variables such as:\n\n        $_   last input line\n        $.   current input line number\n        $~   the match object returned by the last successful pattern match\n        $&   the string matched by last successful pattern match\n        $3   the string matched by the 3rd group of the last successful pattern match\n        $*   sys.argv\n        $>   sys.stdout (default output file)\n        $<   sys.stdint (default input file)\n        $;   input field separator (default value to str.split())\n        $/   record separator (os.linesep)\n        $$   os.getpid()\n\n    Please refer to [English.rb] and [English.pm] for more information.\n\n3)  Lack of a flexible command line import mechanism. For example, Perl\n    has the `-M` options:\n\n        perl -MDigest::MD5=md5_hex  => from Digest::MD5 import md5_hex\n        perl -MDigest::MD5          => import Digest::MD5\n\n    While the CPython interpreter has the `-m` switch, it is not\n    suitable for the task at hand. For example, the following one-liner\n    will run [random\\'s] test suite, instead of printing a random\n    number:\n\n        python -m random -c \"print(random.randint(10))\"\n\nAll these points add up to the verbosity of Python one-liners. The\nfollowing example demonstrates this:\n\n``` bash\n# convert a date to a unix timestamp (using strptime)\nruby -rdate -pe '$_=Date.strptime($_, \"%Y-%m-%d\").strftime(\"%s\")'\nperl -MTime::Piece -pe '$_=Time::Piece->strptime($_, \"%Y-%m-%d\\n\")->epoch()'\npython -c 'import sys,datetime; [sys.stdout.write(datetime.datetime.strptime(\"%Y-%m-%d\", i).strftime(\"%s\") for i in sys.stdin]'\n```\n\nBut why would anyone want to write one-liners in Python, given these\nshortcomings and the available alternatives? I believe that when doing\ninteractive work on the shell, the first solution that comes to mind is\nusually good enough. If that solution is a Python one, why not use it?\n\n# How?\n\nPython comes with all the building blocks for implementing a practical\nmethod of writing one-liners. This module tries to address the issues\noutlined above. The command line interface is kept as close as that of\nRuby and Perl as reasonable.\n\n1)  To help with the processing of input and output, *oneliner* provides\n    the the `-n`, `-p` and `-l` command line switches.\n\n    -   `-n`: assume the following loop around expressions or statements\n        (the distinction will be clarified later):\n\n            for line in sys.stdin:\n                ...\n\n    -   `-p`: like `-n`, but write the value of `line` to stdout at the\n        end of each iteration:\n\n            for line in sys.stdin:\n                ...\n                sys.stdout.write(line)\n\n    -   `-l`: automatic line-ending processing. Roughly equivalent to:\n\n            for line in sys.stdin:\n                line = line.strip(os.linesep)\n                ...\n                sys.stdout.write(line)\n                sys.stdout.write(os.linesep)\n\n2)  Makes the following variables available in the local namespace of\n    each one-liner:\n\n    -   `line`, `L`, `_`: The current input line. Unless the `-l` switch\n        is given, the line separatator will be a part of this string.\n\n    -   `words`, `W`: Corresponds to the value of\n        `re.split(delimiter, line)` where delimiter is the value of the\n        `-d` option. Defaults to `\\s+`.\n\n        The `words` list will return an empty string instead of throwing\n        an `IndexError` when a non-existent item is referenced. This\n        behavior is similar to that of arrays in Ruby and field\n        variables in Awk.\n\n    -   `NR`: Current input line number.\n\n    -   `FN`: Current input file name. If oneliner is processing input\n        from stdin `FN` will be equal to `<stdin>`, otherwise it\n        corresponds to the current input file given on the command line.\n        For example:\n\n            echo example | python -m oneliner -ne '\"%s:%s\\t %s\" % (FN, NR, L)'\n            => <stdin>:1     example\n\n            python -m oneliner -ne '\"%s:%s\\t %s\" % (FN, NR, L)' example.txt\n            => example1.txt:1     line 1\n\n3)  Provide the `-m` and `-M` options and a mini-language for specifying\n    imports. This is best illustrated by an example:\n\n        -m os,sys,re,pickle       => import os, sys, re, pickle\n        -m os -m sys -m re        => import os, sys, re\n        -m os sys re pickle       => import os, sys, re, pickle\n        -m os.path.[*]            => from os.path import *\n        -m os.path.[join,exists]  => from os.path import join, exists\n        -m subprocess=sub         => import subprocess as sub\n        -m datetime.[datetime=dt] => from datetime import datetime as dt\n        -M os.path                => from os.path import *\n\n# Installing\n\nThe latest stable version of *python-oneliner* is available on pypi and\nmay be installed with pip.\n\n``` bash\n$ python -m pip install oneliner\n```\n\nAlternatively, you may simply put the [oneline.py] file anywhere in\n[sys.path]{.title-ref}.\n\n# Todo\n\n-   Support one-liners that don\\'t deal with input/output only. If `-n`\n    or `-p` are not given, *python-oneliner* should behave mostly like\n    `python -c` does.\n-   Persistent variables in statement one-liners.\n-   The result of an expression one-liner is always written to stdout\n    (even if `-n`).\n-   Define the behaviour of multiple expression/statements specified on\n    the command line.\n-   Some means of emulating `BEGIN` and `END` (perhaps a `-b` and `-d`\n    flag?)\n-   Add more examples.\n\n# Similar Projects\n\n-   [Pyp]\n-   [Pyle]\n-   [Funcpy]\n-   [Red]\n-   [Pyfil]\n\n# License\n\n*Python-oneliner* is released under the terms of the [Revised BSD\nLicense].\n\n  [English.rb]: https://github.com/ruby/ruby/blob/trunk/lib/English.rb\n  [English.pm]: http://cpansearch.perl.org/src/GBARR/perl5.005_03/lib/English.pm\n  [random\\'s]: http://hg.python.org/cpython/file/16b1fde2275c/Lib/random.py#l728\n  [oneline.py]: https://raw.githubusercontent.com/gvalkov/python-oneliner/master/oneliner.py\n  [Pyp]: http://code.google.com/p/pyp/\n  [Pyle]: https://github.com/aljungberg/pyle\n  [Funcpy]: http://www.pixelbeat.org/scripts/funcpy\n  [Red]: https://bitbucket.org/johannestaas/red\n  [Pyfil]: https://github.com/ninjaaron/pyfil\n  [Revised BSD License]: https://raw.github.com/gvalkov/python-oneliner/master/LICENSE\n",
    "bugtrack_url": null,
    "license": "Copyright (c) 2012-2024 Georgi Valkov. All rights reserved.  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.  3. Neither the name of author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GEORGI VALKOV BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ",
    "summary": "practical python one-liners",
    "version": "0.3.1",
    "project_urls": {
        "Homepage": "https://github.com/gvalkov/python-oneliner"
    },
    "split_keywords": [
        "oneliner",
        "one-liner"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e7d7c498d2e65421a303279536ceebc79d41d0fb14047a6f446931e6487fc287",
                "md5": "78835996971443050a30baac9bc4d5d8",
                "sha256": "669712a36824fc9b251f649fb2c40c4109ea94a078b339095773153967084827"
            },
            "downloads": -1,
            "filename": "oneliner-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "78835996971443050a30baac9bc4d5d8",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 10195,
            "upload_time": "2024-02-18T17:47:13",
            "upload_time_iso_8601": "2024-02-18T17:47:13.352473Z",
            "url": "https://files.pythonhosted.org/packages/e7/d7/c498d2e65421a303279536ceebc79d41d0fb14047a6f446931e6487fc287/oneliner-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4fbe3a1f7284b5bc64d8f6c63db6a60a069f6aaff33785cd603792fabfad5f73",
                "md5": "f7f08daef71c3f55dd1a0c1424ac11a8",
                "sha256": "3a6d452361f82c249d72c014ad223eaf9a3974508903549abed4bc99589ae06d"
            },
            "downloads": -1,
            "filename": "oneliner-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "f7f08daef71c3f55dd1a0c1424ac11a8",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 10409,
            "upload_time": "2024-02-18T17:47:15",
            "upload_time_iso_8601": "2024-02-18T17:47:15.056816Z",
            "url": "https://files.pythonhosted.org/packages/4f/be/3a1f7284b5bc64d8f6c63db6a60a069f6aaff33785cd603792fabfad5f73/oneliner-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-02-18 17:47:15",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "gvalkov",
    "github_project": "python-oneliner",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "oneliner"
}
        
Elapsed time: 0.18403s