如何在没有终端提示的情况下从IPython会话进行复制


75

通常,我的工作流程涉及在IPython Shell中清理/整理数据。自IPython 5.0版以来,对终端接口进行了所有重大升级,这一点变得特别美妙。因此,假设我尝试整理一些非结构化数据:

In [11]: for i, (num, header, txt) in enumerate(data):
    ...:     header = [e.strip() for e in header.strip().split('\n')]
    ...:     header[4] = header[4].strip(',').split(',')
    ...:     data[i] = (num, header, txt)
    ...:

太棒了,它有效!但是现在,我真的很想将其添加到编辑器中的脚本中。如果从终端复制并粘贴,则会捕获左侧的所有垃圾。我可以在编辑器中轻松地清理它,但是如果我可以将代码直接从终端复制到剪贴板而不用触摸鼠标,也不需要抓住多余的东西,那就太好了。IPython中有这样的功能吗?



1
如果您不想自定义您的IPython设置,print(In[11])则应复制一些内容,但不要在左侧留下垃圾。
user2357112支持Monica 2016年

@ user2357112嗯,尽管这不是理想的选择,但对我来说可以使用。如果您将其添加为答案,但没有更好的显示,我会接受。
juanpa.arrivillaga

Answers:


96

您可以使用%history魔术从会话中提取有趣的部分。它们将在终端中显示,没有任何垃圾。

In [1]: import numpy as np    
In [2]: a = np.random(10)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-83ce219ad17b> in <module>()
----> 1 a = np.random(10)

TypeError: 'module' object is not callable

In [3]: a = np.random.random(10)
In [4]: for i in a:
   ...:     print(i)
   ...:     
0.688626523886
[...]
0.341394850998

如果要保存上面的部分会话,可以使用:

In [5]: %history 1 3-4

import numpy as np
a = np.random.random(10)
for i in a:
    print(i)

在上面的示例中,我曾经%history 1 3-4汇编所有要保留的命令,并省略了不需要的命令(第2行,有错误的命令)。现在,您具有可以很好地复制的会话版本。

写文件

您也可以使用-f FILENAMEas参数将其直接写入文件。

In [8]: %history 1 3-4 -f /tmp/foo.py

但是请小心,这会覆盖现有文件。可以%history魔术文档中找到更多详细信息。


这是一个有用的功能,尽管它也提供了我们在输出中使用的命令,例如,如果我使用%history它的话,下一次也会给出该命令。我认为这就是历史所做的。
bhansa

18

因此,我终于找到了一个实质上正是我想要的解决方案:在IPython中使用Vi模式。在版本5上,这要求:

$ ipython --TerminalInteractiveShell.editing_mode=vi

现在,我可以使用方便的类似vi的可视模式,并随意提取所需!

这会在我的.bash_profile / .bash_rc中导致以下新别名:

alias vpython='ipython --TerminalInteractiveShell.editing_mode=vi'

2
而不是使用别名,你可以添加c.TerminalInteractiveShell.editing_mode = 'vi'~/.ipython/profile_default/ipython_config.py。相信这里的更多细节。
BiBi

5
很好的答案,但仍然如何使用终端提示复制代码?
markroxor

1
与常规剪贴板功能相比,在IPython vim模式下似乎无法像在Vim中那样正常工作。"+y不起作用。
Zaid Gharaybeh,2010年

13

save魔术命令[文件],保存你要到一个文件中输入线; 该-a选项用于“追加”模式,以便将行添加到文件的末尾,而不是覆盖文件。我用它所有的时间。

以您的示例为例:

%save -a myfile.py 11
# the '%' is not necessary
save -a myfile.py 11

然后,您可以继续在IPython中进行编码。

当您有另一个要写入同一文件的命令时,只需键入save然后使用向上箭头即可带回上一次使用“保存”(以便该-a选项和文件名已经存在)并只需编辑该行数。

请注意,您可以指定几行来保存以及行范围:

save -a myfile.py 15 18 19-25

4

在外壳中,您可以先将IPython文件转换为常规Python文件(.py),然后进行清理:

http://ipython.org/ipython-doc/3/notebook/nbconvert.html(请参阅--to脚本格式)

您还可以在笔记本编辑器中将文件下载为Python文件,并在此步骤之后执行清理。


...我认为您不了解,没有IPython文件(假设您的意思是Jupyter笔记本)。整个问题是我在使用外壳的终端中,理想情况下,我根本不想使用鼠标。该%history魔术是最接近,这就是为什么我接受,但它仍然需要一个鼠标,很遗憾。
juanpa.arrivillaga

是的,您是正确的Jupyter笔记本文件(ipynb)格式。
Dutch_Programmer

是的,您是正确的Jupyter笔记本文件(ipynb)格式。我认为您也许可以在终端中运行以下命令:$ ipython nbconvert --to编写<filename> .ipynb脚本以在终端中创建一个可行的文件进行清理(我很抱歉,仅从Python开始)TI获悉从您的帖子中。
Dutch_Programmer

是的,很不幸,我不是在玩Jupyter笔记本,而是在REPL中工作。有时我会这样做,但是由于您所指出的工具以及代码已经是一种纯文本格式的事实,问题就没有了。
juanpa.arrivillaga

有趣的是,您之前将REPL称为Shell或Terminal。对于REPL窗口中的代码,我的大多数编辑器都允许我按住shift-alt键并使用箭头来复制矩形。在示例中,将光标右移至for关键字。这可以在Visual Studio,Atom,VIM等环境中使用。我一直都从REPL复制到编辑器中,没有任何问题。如果这对您很重要并且不能在您的IDE /文本编辑器中使用,那么我建议您考虑使用其他IDE /文本编辑器。
Dutch_Programmer

1

我不认为终端应用程序确实可以访问复制/粘贴缓冲区。您将不得不使用鼠标。如何执行取决于您所使用的终端。大多数现代终端都有某种“矩形选择”或“块选择”模式。

在Windows中,cmd.exe和Powershell的默认矩形选择。如果您使用的是Cygwin的薄荷糖,请按住Alt并用鼠标选择区域。腻子也是如此。

在Linux上(我不知道要用这些-带着一点盐),xterm不支持​​它,Gnome TerminalCtrl用作修饰符,而KDE的Konsole使用Ctrl+ Alt

对于OS X Terminal,Internet告诉我单击时使用。

其他终端(和GNU Screen)可能具有此功能,这只是弄清楚如何激活它的问题。


终端应用程序对剪贴板的访问权限与其他任何应用程序相同。
user2357112支持Monica's
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.