简体   繁体   中英

Search inside ipython history

ipython 's %his command outputs recent commands entered by the user. Is it possible to search within these commands? Something like this:

[c for c in %history if c.startswith('plot')]

EDIT I am not looking for a way to rerun a command, but to locate it in the history list. Of course, sometimes I will want to rerun a command after locating it, either verbatim or with modifications.

EDIT searching with ctr-r and then typing plot gives the most recent command that starts with "plot". It won't list all the commands that start with it. Neither can you search within the middle or the end of the commands

Solution

Expanding PreludeAndFugue's solution here what I was looking for:

[l for l in  _ih if l.startswith('plot')]

here, the if condition can be substituted by a regex

Even better: %hist -g pattern greps your past history for pattern . You can additionally restrict your search to the current session, or to a particular range of lines. See %hist?

So for @BorisGorelik's question you would have to do

%hist -g plot

Unfortunately you cannot do

%hist -g ^plot

nor

%hist -g "^plot"

如果要在历史记录中重新运行命令,请尝试Ctrl-r ,然后尝试搜索字符串。

I usually find myself wanting to search the entire ipython history across all previous and current sessions. For this I use:

from IPython.core.history import HistoryAccessor
hista = HistoryAccessor()
z1 = hista.search('*numpy*corr*')
z1.fetchall()

OR (don't run both or you will corrupt/erase your history)

ip = get_ipython()
sqlite_cursor = ip.history_manager.search('*numpy*corr*')
sqlite_cursor.fetchall()

The search string is not a regular expression. The iPython history_manager uses sqlite's glob * search syntax instead.

Similar to the first answer you can do the following:

''.join(_ih).split('\n')

However, when iterating through the command history items you can do the following. Thus you can create your list comprehension from this.

for item in _ih:
    print item

This is documented in the following section of the documentation: http://ipython.org/ipython-doc/dev/interactive/reference.html#input-caching-system

There is the way you can do it:

''.join(_ip.IP.shell.input_hist).split('\n')

or

''.join(_ip.IP.shell.input_hist_raw).split('\n')

to prevent magick expansion.

from IPython.core.history import HistoryAccessor


def search_hist(pattern,
                print_matches=True,
                return_matches=True,
                wildcard=True):

    if wildcard:
        pattern = '*' + pattern + '*'
    matches = HistoryAccessor().search(pattern).fetchall()

    if not print_matches:
        return matches

    for i in matches:
        print('#' * 60)
        print(i[-1])

    if return_matches:
        return matches
%history [-n] [-o] [-p] [-t] [-f FILENAME] [-g [PATTERN [PATTERN ...]]]
         [-l [LIMIT]] [-u]
         [range [range ...]]

....

-g <[PATTERN [PATTERN …]]>
treat the arg as a glob pattern to search for in (full) history. This includes the saved history (almost all commands ever written). The pattern may contain ‘?’ to match one unknown character and ‘*’ to match any number of unknown characters. Use ‘%hist -g’ to show full saved history (may be very long).

Example (in my history):

In [23]: hist -g cliente*aza
655/58: cliente.test.alguna.update({"orden" : 1, "nuevo" : "azafran"})
655/59: cliente.test.alguna.update({"orden" : 1} , {$set : "nuevo" : "azafran"})
655/60: cliente.test.alguna.update({"orden" : 1} , {$set : {"nuevo" : "azafran"}})

Example (in my history):

In [24]: hist -g ?lie*aza
655/58: cliente.test.alguna.update({"orden" : 1, "nuevo" : "azafran"})
655/59: cliente.test.alguna.update({"orden" : 1} , {$set : "nuevo" : "azafran"})
655/60: cliente.test.alguna.update({"orden" : 1} , {$set : {"nuevo" : "azafran"}})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM