跳转到主要内容

实用的Python单行脚本

项目描述

Python单行脚本

此模块提高了Python作为编写shell单行脚本工具的实用性。简要用法示例

# 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

为什么?

Python是一种优秀的通用脚本语言,拥有丰富的优秀库。尽管其语法的简洁性常被引为一大优点,但我认为对任何形式 语法魔法 的负面态度阻碍了Python成为编写shell单行脚本的实用工具。与Ruby和Perl相比,Python在shell管道中并不适合。编写单行脚本是可能的,但它们的冗长性使得它们不实用。这可能是以下因素造成的

  1. 缺少 read-print-loop 命令行选项。Ruby和Perl提供了 -n-p 开关,使它们假设以下循环在代码周围

    for line in sys.stdin:
        <code>
        if '-p' in options:
            sys.stdout.write(line)
    
  2. 没有 语法魔法 和没有 特殊变量 。Ruby和Perl提供了大量神秘但有用的变量,如

    $_   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()
    

    请参阅English.rbEnglish.pm 了解更多信息。

  3. 缺少灵活的命令行导入机制。例如,Perl有 -M 选项

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

    尽管CPython解释器有 -m 开关,但它不适合手头的任务。例如,以下单行脚本将运行random的测试套件,而不是打印一个随机数

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

所有这些因素加在一起导致了Python单行脚本的冗长性。以下示例展示了这一点

# 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]'

鉴于这些不足和可用的替代方案,为什么有人想用Python编写单行代码?我认为,当在shell上做交互式工作时,首先想到的解决方案通常就足够好。如果这个解决方案是Python的,为什么不使用它呢?

如何做?

Python自带实现编写单行代码的构建块。本模块试图解决上述问题。尽可能使命令行界面与Ruby和Perl的相似。

  1. 为了帮助处理输入和输出,oneliner提供了-n-p-l命令行开关。

    • -n:假设在表达式或语句周围有以下循环(区别将在后面阐明)

      for line in sys.stdin:
          ...
      
    • -p:类似于-n,但在每次迭代的末尾将line的值写入stdout

      for line in sys.stdin:
          ...
          sys.stdout.write(line)
      
    • -l:自动行尾处理。大致相当于

      for line in sys.stdin:
          line = line.strip(os.linesep)
          ...
          sys.stdout.write(line)
          sys.stdout.write(os.linesep)
      
  2. 使以下变量在单行代码的局部命名空间中可用

    • lineL_:当前输入行。除非指定了-l开关,否则行分隔符将是此字符串的一部分。

    • wordsW:对应于re.split(delimiter, line)的值,其中delimiter是-d选项的值。默认为\s+

      当引用不存在的项时,words列表将返回空字符串而不是抛出IndexError。此行为类似于Ruby中的数组以及Awk中的字段变量。

    • NR:当前输入行号。

    • FN:当前输入文件名。如果oneliner正在处理来自stdin的输入,则FN将等于<stdin>,否则它对应于命令行中给出的当前输入文件。例如

      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. 提供-m-M选项以及用于指定导入的迷你语言。这最好通过一个例子来说明

    -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 *
    

安装

最新稳定的python-oneliner版本可在pypi上找到,可以使用pip进行安装。

$ python -m pip install oneliner

或者,您可以将oneline.py文件放在[sys.path]{.title-ref]中的任何位置。

待办事项

  • 支持仅处理输入/输出的单行代码。如果没有提供-n-ppython-oneliner应该表现得与python -c类似。
  • 单行语句中的持久变量。
  • 表达式单行代码的结果始终写入stdout(即使-n)。
  • 定义命令行上指定的多个表达式/语句的行为。
  • 一些模拟BEGINEND(可能是一个-b-d标志)的方法
  • 添加更多示例。

类似项目

许可

Python-oneliner修订版BSD许可证下发布。

项目详情


下载文件

下载适合您平台的文件。如果您不确定要选择哪个,请了解更多关于安装包的信息。

源分发

oneliner-0.3.1.tar.gz (10.4 kB 查看散列)

上传于

构建的发行版

oneliner-0.3.1-py3-none-any.whl (10.2 kB 查看哈希值)

上传于 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面