像列输出 - python库 [英] apt like column output - python library

查看:220
本文介绍了像列输出 - python库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Debian的apt工具输出结果是统一宽度的列。例如,尝试运行aptitude search svn..所有的名字出现在同一宽度的第一列。

现在如果你调整终端的大小,列宽是相应的调整。

是否有一个Python库,使人能做到这一点?请注意,图书馆必须知道终端宽度,并采取一个表作为输入 - 这可能是,例如, [('rapidsvn','一个用于颠覆的GUI客户端'),... ] ..你也可以指定第一列(或任何列)的最大宽度。另外请注意,如果超过终端宽度,下面第二列中的字符串将被修剪。因此,不会引入不需要的第二行。

  $ aptitude search svn 
[...]
p python-svn-dbg - 一个Subversion的Python接口(d
v python2.5-svn -
v python2。 6-svn -
p rapidsvn - 用于颠覆的GUI客户端
p statsvn - SVN信息库统计信息
p svn-arch-mirror - 从Subversion到Arch的单向镜像r
p svn-autoreleasedeb - 自动发布/上传debian软件包
p svn-buildpackage - 帮助程序维护Debian软件包
p svn-load - Subvers的增强导入工具ion
p svn-workbench - Subversion的工作台
p svnmailer - 可扩展的Subversion提交通知t
p websvn - subversion版本库的接口writt
$

编辑 :(回应Alex的回答)输出将类似于'aptitude search' 1)只有最后一列(这是唯一一列中具有最长字符串的列)被修剪,2)通常只有2-4列,但是最后一列(描述至少有一半的终端宽度。 3)所有的行都包含相同数量的列,4)所有的条目都只是字符串

解决方案

我不认为有一个通用的,跨平台的方式来获取终端的宽度 - 绝对不是查看COLUMNS环境变量(请参阅​​我对该问题的评论)。在Linux和Mac OS X上(我希望所有的现代Unix版本),

  curses.wrapper(lambda _:curses.tigetnum ('cols'))

返回列数;但是我不知道 wcurses 是否支持Windows。



一旦你有(如果你坚持,或通过诅咒,或从甲骨文,或默认为80,或任何其他方式,你可以从os.environ ['COLUMNS'])输出宽度,其余的
是相当可行的。这是一项非常精细的工作,有很多错误的机会,而且很容易出现很多你没有完全清楚的详细规范,例如:哪一列被切断,以避免包装 - 它总是最后一个,还是...?如何根据您的问题在样本输出中显示3列,只有两列通过...?如果不是所有的行都有相同数量的列,那么应该发生什么?表中的所有条目是否必须是字符串?以及许多其他许多这种类似的奥秘。所以,对所有没有表达的规格进行一些随意的猜测,一种方法可能是类似的。 ..:

  import sys 

def colprint(totwidth,table):
numcols = max(row(row)in table)
#确保所有行都有> = numcols列,也许是空的
padded = [row + numcols *('',)for table in table]
#计算列宽,包括分隔空间(除了最后一列)
widths = [1 + max(len(x)for x in column)for zip(* padded)]
widths [-1] - = 1
#从右边拖放或截断列以适合
while sum(widths)> totwidth:
mustlose = sum(widths) - totwidth
if widths [-1]< = mustlose:
del widths [-1]
else:
widths [-1] - = mustlose
break
#最后,输出阶段!
为填充行:
为w,我在zip(宽度,行):
sys.stdout.write('%* s'%(-w,i [:w] ))
sys.stdout.write('\\\
')


Debian's apt tool outputs results in uniform width columns. For instance, try running "aptitude search svn" .. and all names appear in the first column of the same width.

Now if you resize the terminal, the column width is adjusted accordingly.

Is there a Python library that enables one to do this? Note that the library has to be aware of the terminal width and take a table as input - which could be, for instance, [('rapidsvn', 'A GUI client for subversion'), ...] .. and you may also specify a max-width for the first column (or any column). Also note how the string in the second column below is trimmed if exceeds the terminal width .. thus not introducing the undesired second line.

$ aptitude search svn
[...]
p   python-svn-dbg                    - A(nother) Python interface to Subversion (d
v   python2.5-svn                     -                                            
v   python2.6-svn                     -                                            
p   rapidsvn                          - A GUI client for subversion                
p   statsvn                           - SVN repository statistics                  
p   svn-arch-mirror                   - one-way mirroring from Subversion to Arch r
p   svn-autoreleasedeb                - Automatically release/upload debian package
p   svn-buildpackage                  - helper programs to maintain Debian packages
p   svn-load                          - An enhanced import facility for Subversion 
p   svn-workbench                     - A Workbench for Subversion                 
p   svnmailer                         - extensible Subversion commit notification t
p   websvn                            - interface for subversion repositories writt
$

EDIT: (in response to Alex's answer below) ... the output will be similar to 'aptitude search' in that 1) only the last column (which is the only column with the longest string in a row) is to be trimmed, 2) there are typically 2-4 columns only, but the last column ("description") is expected to take at least half the terminal width. 3) all rows contain equal number of columns, 4) all entries are strings only

解决方案

I don't think there's a general, cross-platform way to "get the width of the terminal" -- most definitely NOT "look at the COLUMNS environment variable" (see my comment on the question). On Linux and Mac OS X (and I expect all modern Unix versions),

curses.wrapper(lambda _: curses.tigetnum('cols'))

returns the number of columns; but I don't know if wcurses supports this in Windows.

Once you do have (from os.environ['COLUMNS'] if you insist, or via curses, or from an oracle, or defaulted to 80, or any other way you like) the desired output width, the rest is quite feasible. It's finnicky work, with many chances for off-by-one kinds of errors, and very vulnerable to a lot of detailed specs that you don't make entirely clear, such as: which column gets cut to avoid wrapping -- it it always the last one, or...? How come you're showing 3 columns in the sample output when according to your question only two are passed in...? what is supposed to happen if not all rows have the same number of columns? must all entries in table be strings? and many, many other mysteries of this ilk.

So, taking somewhat-arbitrary guesses for all the specs that you don't express, one approach might be something like...:

import sys

def colprint(totwidth, table):
  numcols = max(len(row) for row in table)
  # ensure all rows have >= numcols columns, maybe empty
  padded = [row+numcols*('',) for row in table]
  # compute col widths, including separating space (except for last one)
  widths = [ 1 + max(len(x) for x in column) for column in zip(*padded)]
  widths[-1] -= 1
  # drop or truncate columns from the right in order to fit
  while sum(widths) > totwidth:
    mustlose = sum(widths) - totwidth
    if widths[-1] <= mustlose:
      del widths[-1]
    else:
      widths[-1] -= mustlose
      break
  # and finally, the output phase!
  for row in padded:
    for w, i in zip(widths, row):
      sys.stdout.write('%*s' % (-w, i[:w]))
    sys.stdout.write('\n')

这篇关于像列输出 - python库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆