xdev.search_replace module

Python implementations of sed, grep, and find

Porting from ~/local/rob/rob/rob_nav.py / ubelt

class xdev.search_replace.GrepResult(fpath, pattern=None)[source]

Bases: NiceRepr

Manage and format results from grep

append(lx, line)[source]
format_text(color=True)[source]
xdev.search_replace.sed(regexpr, repl, dpath=None, include=None, exclude=None, dirblocklist=None, recursive=True, dry=False, verbose=1)[source]

Execute a sed on multiple files.

Parameters:
  • regexpr (str | Pattern) – pattern to find

  • repl (str) – the text to replace the found pattern with

  • dpath (str | None) – passed to find().

  • include (str | List[str] | MultiPattern | None) – passed to find().

  • exclude (str | List[str] | MultiPattern | None) – passed to find().

  • dirblocklist (str | List[str] | MultiPattern | None) – passed to find().

  • recursive (bool) – passed to find().

  • dry (bool) – if True does not apply edits

  • verbose (int) – verbosity level

Example

>>> from xdev.search_replace import *  # NOQA
>>> from xdev.search_replace import _create_test_filesystem
>>> dpath = _create_test_filesystem()['root']
>>> sed('a', 'x', dpath=dpath, dry=True)
xdev.search_replace.grep(regexpr, dpath=None, include=None, exclude=None, recursive=True, dirblocklist=None, verbose=1)[source]

Execute a grep on multiple files.

Parameters:
  • regexpr (str | Pattern) – pattern to find

  • dpath (str | None) – passed to find().

  • include (str | List[str] | MultiPattern | None) – passed to find().

  • exclude (str | List[str] | MultiPattern | None) – passed to find().

  • recursive (bool) – passed to find().

  • dirblocklist (str | List[str] | MultiPattern | None) – passed to find().

  • verbose (int) – verbosity level

Return type:

List[GrepResult]

Example

>>> from xdev.search_replace import *  # NOQA
>>> from xdev.search_replace import _create_test_filesystem
>>> dpath = _create_test_filesystem()['root']
>>> grep('a', dpath=dpath)
xdev.search_replace.find(pattern=None, dpath=None, include=None, exclude=None, dirblocklist=None, type=None, recursive=True, followlinks=False)[source]

Find all paths in a root subject to a search criterion

Parameters:
  • pattern (str | Pattern | None) – The glob pattern the path name must match to be returned

  • dpath (str | Pattern | None) – The root directory to search. Can also be a filepath, in which case, that is the only filepath considered. NOTE: in the future, this argument may change to path to indicate specifying a filepath is allowed. Defaults to cwd.

  • include (str | List[str] | MultiPattern | None) – Pattern or list of patterns. If specified, search only files whose base name matches this pattern. By default the pattern is GLOB. This only applies to the final name. Directories that do not match this name will still be traversed.

  • exclude (str | List[str] | MultiPattern | None) – Pattern or list of patterns. Skip any file with a name suffix that matches the pattern. By default the pattern is GLOB. This ONLY applies to the final name. Directories that match an exclude pattern will still be traversed. Use dirblocklist to specify patterns to exclude intermediate directories from traversal.

  • dirblocklist (str | List[str] | MultiPattern | None) – Any directory name matching this pattern will be removed from traversal.

  • type (str | List[str] | None) – A list of 1 character codes indicating what types of file can be returned. Currently we only allow either “f” for file or “d” for directory. Symbolic links are not currently distinguished. In the future we may support posix codes, see [1]_ for details.

  • recursive – search all subdirectories recursively

  • followlinks (bool, default=False) – if True will follow directory symlinks

References

_[1] https://linuxconfig.org/identifying-file-types-in-linux

Todo

mindepth

maxdepth

ignore_case

regex_match

Example

>>> from xdev.search_replace import *  # NOQA
>>> from xdev.search_replace import _create_test_filesystem
>>> dpath = _create_test_filesystem()['root']
>>> paths = list(find(pattern='*', dpath=dpath))
>>> assert len(paths) == 5
>>> paths = list(find(pattern='*', dpath=dpath, type='f'))
>>> assert len(paths) == 4
xdev.search_replace.sedfile(fpath, regexpr, repl, dry=False, verbose=1)[source]

Execute a search and replace on a particular file

Parameters:
  • fpath (str | PathLike) – file to search / replace on

  • regexpr (str | Pattern) – pattern to find

  • repl (str) – the text to replace the found pattern with

  • dry (bool) – if True does not apply edits

  • verbose (int) – verbosity level

Returns:

changed lines

Return type:

List[Tuple[str, str]]

Todo

  • [ ] Store “SedResult” class, with lazy execution

Example

>>> from xdev.search_replace import *  # NOQA
>>> from xdev.search_replace import _create_test_filesystem
>>> fpath = _create_test_filesystem()['contents'][1]
>>> changed_lines1 = sedfile(fpath, 'a', 'x', dry=True, verbose=1)
>>> changed_lines2 = sedfile(fpath, 'a', 'x', dry=False, verbose=0)
>>> assert changed_lines2 == changed_lines1
>>> changed_lines3 = sedfile(fpath, 'a', 'x', dry=False, verbose=0)
>>> assert changed_lines3 != changed_lines2
xdev.search_replace.grepfile(fpath, regexpr, verbose=1)[source]

Exceute grep on a single file

Parameters:
  • fpath (str | PathLike) – file to search

  • regexpr (str | Pattern) – pattern to find

  • verbose (int) – verbosity level

Returns:

None | GrepResult

Example

>>> from xdev.search_replace import *  # NOQA
>>> from xdev.search_replace import _create_test_filesystem
>>> fpath = _create_test_filesystem()['contents'][1]
>>> grep_result = grepfile(fpath, r'\bb\b')
>>> print('grep_result = {}'.format(grep_result))
xdev.search_replace.greptext(text, regexpr, fpath=None, verbose=1)[source]

Exceute grep on text

Parameters:
  • text (str) – text to search

  • regexpr (str | Pattern) – pattern to find

  • verbose (int) – verbosity level

Returns:

None | GrepResult

xdev.search_replace._create_test_filesystem()[source]