TextTools¶
The handful of Unix text idioms whose Python equivalent is non-obvious: awk-style field extraction, multi-key sort, and uniq.
TextTools is intentionally small. It wraps only the operations where native Python is fiddly to hand-roll. For the trivial cases, reach for the language directly: filter lines with re.search in a comprehension, slice with lines[:n] / lines[-n:], and substitute with re.sub.
Usage¶
from pymdm import TextTools
tools = TextTools()
# awk -F: '{print $1}' /etc/passwd
usernames = tools.awk(passwd_text, field=1, delimiter=":")
# the classic `sort | uniq -c` count-occurrences pipeline
sorted_lines = tools.sort(["http", "ssh", "http", "ftp", "ssh", "http"])
counts = tools.uniq(sorted_lines, count=True)
# -> ["1 ftp", "3 http", "2 ssh"]
Each method accepts input as either a multi-line str or a list[str]. Pass an optional MdmLogger to the constructor for debug-level call tracing.
- class TextTools(logger: MdmLogger | None = None)[source]¶
Bases:
objectText utilities for the Unix idioms Python doesn’t make obvious.
- Parameters:
logger (MdmLogger | None)
- awk(text: str | list[str], *, field: int | None = None, fields: list[int] | None = None, delimiter: str | None = None, filter: str | None = None, output_separator: str = ' ') list[str][source]¶
Extract one or more 1-indexed fields per line (mirrors a simplified
awk -F<delim> '/filter/ {print $field}').This is a deliberately small subset of
awk: field extraction with an optional row filter. For more complex transformations, use a list comprehension.- Parameters:
text (str | list[str]) – Input text as a multi-line string or a list of lines
field (int | None, optional) – A single 1-indexed field to extract. Mutually exclusive with
fields.fields (list[int] | None, optional) – A list of 1-indexed fields to extract, joined by
output_separator. Mutually exclusive withfield.delimiter (str | None, optional) – Field delimiter.
None(default) splits on any whitespace (matches defaultawkbehavior).filter (str | None, optional) – Optional regex; only rows matching
filtercontribute to the output (likeawk '/pattern/ {...}').output_separator (str, optional) – Separator used when joining multiple fields per row, defaults to a single space
- Returns:
List of extracted strings, one per matched row. Rows with out-of-range field indices contribute empty strings for those fields (matches
awkbehavior).- Return type:
- Raises:
ValueError – When neither
fieldnorfieldsis given, or when both are givenre.error – When
filteris not a valid Python regex
- sort(text: str | list[str], *, reverse: bool = False, numeric: bool = False, unique: bool = False, field: int | None = None, delimiter: str | None = None) list[str][source]¶
Sort lines (mirrors
sort).- Parameters:
text (str | list[str]) – Input text as a multi-line string or a list of lines
reverse (bool, optional) – Sort in descending order (like
sort -r), defaults to Falsenumeric (bool, optional) – Sort numerically rather than lexicographically (like
sort -n). Non-numeric keys sort after numeric keys. Defaults to Falseunique (bool, optional) – Remove duplicate lines after sorting (like
sort -u), defaults to Falsefield (int | None, optional) – 1-indexed sort key field. When given, sort by that field instead of the whole line. Defaults to None.
delimiter (str | None, optional) – Field delimiter when
fieldis given.Nonesplits on any whitespace.
- Returns:
Sorted list of lines
- Return type:
- uniq(text: str | list[str], *, count: bool = False, duplicates_only: bool = False, unique_only: bool = False) list[str][source]¶
Collapse consecutive duplicate lines (mirrors
uniq).Like the bash
uniq, this assumes input is already sorted — it only collapses consecutive duplicates. Pair withsort()for the commonsort | uniqidiom.- Parameters:
text (str | list[str]) – Input text as a multi-line string or a list of lines
count (bool, optional) – Prefix each line with its occurrence count (like
uniq -c), defaults to Falseduplicates_only (bool, optional) – Emit only lines that appeared more than once (like
uniq -d). Mutually exclusive withunique_only.unique_only (bool, optional) – Emit only lines that appeared exactly once (like
uniq -u). Mutually exclusive withduplicates_only.
- Returns:
Deduplicated list of lines
- Return type:
- Raises:
ValueError – When both
duplicates_onlyandunique_onlyare True