cape.filecntl.filecntl: File control base module

This provides common methods to control objects for various specific files. This includes various methods for reading files, splitting it into sections, and replacing lines based on patterns or regular expressions.

File manipulation classes for specific files (such as pyCart.inputCntl.InputCntl for Cart3D input.cntl files) are built off of this module and its main class. A possibly incomplete list of class built on this class is given below.

class cape.filecntl.filecntl.FileCntl(fname=None)

Base file control class

The lines of the file can be split into sections based on a regular expression (see cape.filecntl.FileCntl.SplitToSections()); most methods will keep the overall line list and the section breakout consistent.

Call:
>>> fc = FileCntl(fname)
Inputs:
fname: str

Name of file to read from and manipulate

Data members:
fc.fname: str

Name of file instance was read from

fc.lines: list[str]

List of all lines in the file (to use for replacement)

fc.SectionNames: list[str]

List of section titles if present

fc.Section: dict (list[str])

Dictionary of the lines in each section, if present

AppendLine(line: str)

Append a line of text to fc.lines

Call:
>>> fc.AppendLine(line)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

line: str

String to add

Versions:
  • 2014-06-03 @ddalle: v1.0

AppendLineToSection(sec: str, line: str)

Append a line of text to a section

Call:
>>> fc.AppendLineToSection(sec, line)
Inputs:
fc: pyCart.fileCntl.FileCntl

File control instance

sec: str

Name of section to update

line: str

String to add

Versions:
  • 2014-06-03 @ddalle: v1.0

AssertSection(sec: str)

Assert that a certain section is present

Call:
>>> fc.AssertSection(sec)
Inputs:
fc: cape.filecntl.FileCntl

File control instance, defaults to fc.fname

sec: str

Name of section to check for

Versions:
  • 2014-06-03 @ddalle: v1.0

DeleteLineInSectionSearch(sec: str, reg: str, nmax=None, imin=0) int

Delete lines that start with given text up to count times

Call:
>>> n = fc.DeleteLineInSectionSearch(sec, reg, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to search

reg: str

Regular expression search for

nmax: {None} | int

Maximum number of lines to delete

imin: {0} | int

Index of first line from which to start search

Outputs:
n: int

Number of deletions made

Effects:

Lines in fc.lines that match reg are removed

Versions:
  • 2023-12-30 @ddalle: v1.0

DeleteLineInSectionStartsWith(sec: str, start: str, nmax=None, imin=0) int

Delete lines based on start text and section name

Call:
>>> n = fc.DeleteLineInSectionStartsWith(sec, start, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to search

start: str

Line-starting string to search for

nmax: {None} | int

Maximum number of lines to delete

imin: {0} | int

Index of first line from which to start search

Outputs:
n: int

Number of deletions made

Effects:

Lines in fc.Section[sec] may be removed if they start with start.

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2023-12-29 @ddalle: v2.0; use _delete_line()

DeleteLineSearch(reg: str, nmax=None, imin=0) int

Delete lines that start with given text up to count times

Call:
>>> n = fc.DeleteLineSearch(reg, nmax=None, imin=0)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

reg: str

Regular expression search for

nmax: {None} | int

Maximum number of lines to delete

imin: {0} | int

Index of first line from which to start search

Outputs:
n: int

Number of deletions made

Effects:

Lines in fc.lines that match reg are removed

Versions:
  • 2023-12-30 @ddalle: v1.0

DeleteLineStartsWith(start: str, nmax=None, imin=0) int

Delete lines that start with given text up to count times

Call:
>>> n = fc.DeleteLineStartsWith(start, nmax=None, imin=0)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

start: str

Line-starting string to search for

nmax: {None} | int

Maximum number of lines to delete

imin: {0} | int

Index of first line from which to start search

Outputs:
n: int

Number of deletions made

Effects:

Lines in fc.lines that start with start are removed

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2023-12-29 @ddalle: v2.0; use _delete_line()

GetIndexInSectionSearch(sec: str, reg: str, nmax=None, imin=0) list

Find lines in a given section that start with a regex

Call:
>>> i = fc.GetIndexInSectionSearch(sec, nmax=None, imin=0)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to search in

reg: str

Regular expression to match beginning of line

nmax: {None} | int

Maximum number of matches to search for

imin: {0} | int

Index of first line to consider

Outputs:
i: list[int]

List of indices of lines in section that match pattern

Versions:
  • 2014-02-28 @ddalle: v1.0

  • 2024-01-03 @ddalle: v2.0; use _find_line()

GetIndexInSectionStartsWith(sec: str, start: str, nmax=None, imin=0) list

Find lines in a given section with given start string

Call:
>>> i = fc.GetIndexInSectionStartsWith(sec, start)
>>> i = fc.GetIndexInSectionStartsWith(sec, start, n)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to search in

start: str

Line start target

nmax: {None} | int

Maximum number of matches to search for

imin: {0} | int

Index of first line to consider

Outputs:
i: list[int]

List of indices of lines in section that match pattern

Versions:
  • 2014-02-28 @ddalle: v1.0

  • 2024-01-03 @ddalle: v2.0; use _find_line()

GetIndexSearch(reg: str, nmax=None, imin=0) list

Find lines that start with a given regular expression

Call:
>>> i = fc.GetIndexSearch(reg)
>>> i = fc.GetIndexSearch(reg, n)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

reg: str

Regular expression to match beginning of line

nmax: {None} | int

Maximum number of matches to search for

imin: {0} | int

Index of first line to consider

Outputs:
i: list[int]

List of lines that match pattern

Versions:
  • 2014-02-28 @ddalle: v1.0

  • 2024-01-03 @ddalle: v2.0; use _find_line()

GetIndexStartsWith(start: str, nmax=None, imin=0) list

Find indices of lines that start with a given literal pattern

Call:
>>> i = fc.GetIndexStartsWith(start, imin=0, nmax=None)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

start: str

Line start target

nmax: {None} | int

Maximum number of matches to search for

imin: {0} | int

Index of first line to consider

Outputs:
i: list[int]

List of lines that match pattern

Versions:
  • 2015-02-28 @ddalle: v1.0

  • 2024-01-03 @ddalle: v2.0; use _find_line()

GetLineInSectionSearch(sec, reg, nmax=None, imin=0)

Find lines in a given section that start specified regex

Call:
>>> lines = fc.GetLineInSectionSearch(sec, reg)
>>> lines = fc.GetLineInSectionSearch(sec, reg, n)
Inputs:
fc: pyCart.fileCntl.FileCntl

File control instance

sec: str

Name of section to search in

reg: str

Regular expression to match beginning of line

nmax: {None} | int

Maximum number of matches to search for

imin: {0} | int

Index of first line to consider

Outputs:
lines: list[str]

List of lines that match pattern

Versions:
  • 2014-06-10 @ddalle: v1.0

  • 2024-01-03 @ddalle: v2.0; use _find_line()

GetLineInSectionStartsWith(sec: str, start: str, nmax=None, imin=0) list

Find lines in a given section that start specified target

Call:
>>> lines = fc.GetLineInSectionStartsWith(sec, start, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to search in

start: str

Target line start

nmax: {None} | int

Maximum number of matches to search for

imin: {0} | int

Index of first line to consider

Outputs:
lines: list[str]

List of lines that match pattern

Versions:
  • 2014-06-10 @ddalle: v1.0

  • 2024-01-03 @ddalle: v2.0; use _find_line()

GetLineSearch(reg: str, nmax=None, imin=0) list

Find lines that start with a given regular expression

Call:
>>> lines = fc.GetLineSearch(reg, nmax=None, imin=0)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

reg: str

Regular expression to match beginning of line

nmax: {None} | int

Maximum number of matches to search for

imin: {0} | int

Index of first line to consider

Outputs:
lines: list[str]

List of lines that match pattern

Versions:
  • 2014-06-10 @ddalle: v1.0

  • 2024-01-03 @ddalle: v2.0; use _find_line()

GetLineStartsWith(start: str, nmax=None, imin=0) list

Find lines that start with a given literal pattern

Call:
>>> lines = fc.GetLineStartsWith(start, nmax=None, imin=0)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

start: str

String to test as match for beginning of each line

nmax: {None} | int

Maximum number of matches to search for

imin: {0} | int

Index of first line to consider

Outputs:
lines: list[str]

List of lines that match pattern

Versions:
  • 2014-06-10 @ddalle: v1.0

  • 2024-01-03 @ddalle: v2.0; use _find_line()

InsertLine(i: int, line: str)

Insert a line of text somewhere into the text

Call:
>>> fc.InsertLine(i, line)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

i: int

Index to which to insert the line

line: str

String to add

Versions:
  • 2014-06-03 @ddalle: v1.0

InsertLineToSection(sec: str, i: int, line: str)

Insert a line of text somewhere into the text of a section

Call:
>>> fc.InsertLineToSection(sec, i, line)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to update

i: int

Index to which to insert the line

line: str

String to add

Effects:

A line is inserted to fc.Section[sec]

Versions:
  • 2014-06-03 @ddalle: v1.0

PrependLine(line: str)

Prepend a line of text to fc.lines

Call:
>>> fc.PrependLine(line)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

line: str

String to add

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2023-12-29 @ddalle: v2.0; use _insert_line()

PrependLineToSection(sec: str, line: str)

Prepend a line of text to a section

Call:
>>> fc.PrependLineToSection(sec, line)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to update

line: str

String to add

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2023-12-29 @ddalle: v2.0; use _insert_line()

  • 2024-01-14 @ddalle: v2.1; debug v2.0, 0->1

Read(fname: str)

Read text from file

Call:
>>> fc.Read(fname)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

fname: str

Name of file to read from

Effects:
fc.lines: list

List of lines in file is created

fc._updated_sections: bool

Whether section breakouts have been updated

fc._updated_lines: bool

Flag for update status of global lines

Versions:
  • 2014-06-03 @ddalle: v1.0

ReplaceLineInSectionSearch(sec: str, reg: str, line, nmax=None, imin=0) int

Find all lines in a certain section that start with a specified regular expression and replace the entire lines with the specified text.

Call:
>>> n = fc.ReplaceLineInSectionSearch(sec, reg, line, **kw)
>>> n = fc.ReplaceLineInSectionSearch(sec, reg, lines, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to search in

reg: str

Regular expression to search for at beginning of each line

line: str

String to replace every match with

lines: list

List of strings to match first len(lines) matches with

nmax: {None} | int

Make at most nmax substitutions

imin: {0} | int

Do not make replacements for matches with index < imin

Outputs:
n: int

Number of matches found

Effects:

Some lines in fc.Section[sec] may be replaced.

See also:

This function is similar to pyCart.fileCntl.FileCntl.ReplaceLineSearch() except that the search is restricted to a specified section.

Versions:
  • 2014-06-04 @ddalle: v1.0

  • 2023-12-29 @ddalle: v2.0; use _replace_line()

ReplaceLineInSectionStartsWith(sec: str, start: str, line, nmax=None, imin=0) int

Make replacements within section based on starting string

Find all lines in a certain section that start with a specified literal string and replace the entire line with the specified text.

Call:
>>> n = fc.ReplaceLineInSectionStartsWith(sec, start, line, **kw)
>>> n = fc.ReplaceLineInSectionStartsWith(sec, start, lines, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to search in

start: str

String to test as literal match for line start

line: str

String to replace every match with

lines: list

List of replacement strings

nmax: {None} | int > 0

Make at most nmax substitutions

imin: {0} | int >= 0

Do not make replacements for matches with index < imin

Outputs:
n: int

Number of matches found

Effects:

Some lines in fc.Section[sec] may be replaced.

See also:

This function is similar to cape.filecntl.FileCntl.ReplaceLineStartsWith() except that the search is restricted to a specified section.

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2023-12-26 @ddalle: v1.1; reduce lines; fix imin

  • 2023-12-29 @ddalle: v2.0; use _replace_line()

ReplaceLineSearch(reg: str, line, nmax=None, imin=0) int

Replace lines based on initial regular expression

Find all lines that begin with a certain regular expression and replace them with another string. Note that the entire line is replaced, not just the regular expression.

Leading spaces are ignored during the match tests.

Call:
>>> n = fc.ReplaceLineSearch(reg, line, imin=0, nmax=None)
>>> n = fc.ReplaceLineSearch(reg, lines, imin=0, nmax=None)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

reg: str

Target regular expression for line starts

line: str

String to replace every match with

lines: list

Multiple replacements

nmax: {None} | int

Make at most nmax substitutions

imin: {0} | int

Do not make replacements for matches with index < imin

Outputs:
n: int

Number of matches found

Effects:

fc.lines: Some of the lines may be affected fc._updated_lines: Set to True

Examples:

Suppose that fc has the following two lines.

Mach      8.00   # some comment\n

Mach    4\n

Then this example will replace both lines with Mach 2.0

>>> fc.ReplaceLineSearch('Mach\s+[0-9.]+', 'Mach 2.0')

This example replaces each line with a different value for the Mach number.

>>> fc.ReplaceLineSearch('Mach\s+[0-9.]+',
    ['Mach 2.0', 'Mach 2.5'])

Finally, this example is different from the first example in that it will replace the first line and then quit before it can find the second match.

>>> fc.ReplaceLineSearch('Mach\s+[0-9.]+', ['Mach 2.0'])
Versions:
  • 2014-06-04 @ddalle: v1.0

  • 2023-12-29 @ddalle: v2.0; use _replace_line()

ReplaceLineStartsWith(start: str, line: str, nmax=None, imin=0) int

Replace lines starting with fixed text

Find all lines that begin with a certain string and replace them with another string. Note that the entire line is replaced, not just the initial string.

Leading spaces are ignored during the match tests.

Call:
>>> n = fc.ReplaceLineStartsWith(start, line, **kw)
>>> n = fc.ReplaceLineStartsWith(start, lines, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

start: str

String to test as literal match for beginning of line

line: str

String to replace every match with

lines: list

List of strings for replacements

nmax: {None} | int > 0

Make at most nmax substitutions

imin: {0} | int >= 0

Do not make replacements for matches with index < imin

Outputs:
n: int

Number of matches found

Effects:

fc.lines: Some of the lines may be affected fc._updated_lines: Set to True

Examples:

Suppose that fc has the following two lines.

Mach      8.00   # some comment\n

Mach      Mach_TMP\n

Then this example will replace both lines with the string Mach 4.0

>>> fc.ReplaceLineStartsWith('Mach', 'Mach 4.0')

This example replaces each line with a different value for the Mach number.

>>> fc.ReplaceLineStartsWith(
    'Mach', ['Mach 2.0', 'Mach 4.0']

Finally, this example is different from the first example in that it will replace the first line and then quit before it can find the second match.

>>> fc.ReplaceLineStartsWith('Mach', ['Mach 4.0'])
Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2019-06-19 @ddalle: v1.1; add imin and nmax

  • 2023-12-26 @ddalle: v1.2; fix output w/ imin

  • 2023-12-29 @ddalle: v2.0; use _replace_line()

ReplaceOrAddLineSearch(reg: str, line: str, i=None, **kw)

Replace a line identified by regex, or add new line

Replace a line that starts with a given regular expression or add the line if no matches are found.

Call:
>>> fc.ReplaceOrAddLineSearch(reg, line, **kw)
>>> fc.ReplaceOrAddLineSearch(reg, line, i, **kw)
Inputs:
fc: pyCart.fileCntl.FileCntl

File control instance

reg: str

Regular expression to match beginning of line

line: str

String to replace first match with

i: int

Location to add line (by default it is appended)

nmax: {None} | int

Make at most nmax substitutions

imin: {0} | int

Do not make replacements for matches with index < imin

Effects:

Replaces line in section fc.lines or adds it if not found

Versions:
  • 2014-06-04 @ddalle: v1.0

  • 2023-12-30 @ddalle: v1.1; use _insert_line()

ReplaceOrAddLineStartsWith(start: str, line: str, i=None, **kw)

Replace a line or add a new one

Replace a line that starts with a given literal string or add the line if no matches are found.

Call:
>>> fc.ReplaceOrAddLineStartsWith(start, line, **kw)
>>> fc.ReplaceOrAddLineStartsWith(start, line, i, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

start: str

Target beginning of line to replace

line: str

String to replace every match with

i: {None} | int

Location to add line, negative ok, (default is append)

nmax: {None} | int > 0

Make at most nmax substitutions

imin: {0} | int >= 0

Do not make replacements for matches with index < imin

Effects:

Replaces line in section fc.lines or adds it if not found

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2023-12-28 @ddalle: v1.1; use _insert_line()

ReplaceOrAddLineToSectionSearch(sec: str, reg: str, line: str, i=None, **kw)

Replace a line in a specified section

Replace a line in a specified section that starts with a given regular expression or add the line to the section if no matches are found.

Call:
>>> fc.ReplaceOrAddLineToSectionStartsWith(sec, reg, line)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to search in

reg: str

Regular expression to match beginning of line

line: str

String to replace every match with

i: {`None} | int

Location to add line (by default it is appended)

nmax: {None} | int

Make at most nmax substitutions

imin: {0} | int

Do not make replacements for matches with index < imin

Effects:

Replaces line in fc.Section[sec] or adds it if not found

Versions:
  • 2014-06-04 @ddalle: v1.0

ReplaceOrAddLineToSectionStartsWith(sec: str, start: str, line: str, i=None, **kw)

Replace a line or add a new one (within section)

Replace a line in a specified section that starts with a given literal string or add the line to the section if no matches are found.

Call:
>>> fc.ReplaceOrAddLineToSectionStartsWith(sec, start, line)
>>> fc.ReplaceOrAddLineToSectionStartsWith(
    sec, start, line, i=None, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

sec: str

Name of section to search in

start: str

Target line start for replacement

line: str

String to replace every match with

i: {None} | int

Location to add line (by default it is appended)

nmax: {None} | int

Make at most nmax substitutions

imin: {0} | int

Do not make replacements for matches with index < imin

Effects:

Replaces line in fc.Section[sec] or adds it if not found

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2023-12-28 @ddalle: v1.1; use _insert_line()

SplitToBlocks(reg='\\$__([\\w_]+)', ngr=1, **kw)

Split lines into sections based on start and end

Call:
>>> fc.SplitToBlocks()
>>> fc.SplitToBlocks(reg="\$__([\w_]+)", ngr=1, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

reg: str

Regular expression for recognizing the start of a new section. By default this looks for sections that start with "$__" as inCart3D input.cntl files. The regular expression must also include a group (meaning content between parentheses) to capture the name of the section. Thus the default value of "\$__([\w_]+)" finds any name that consists of word characters and/or underscores.

ngr: {1} | int | str

Group number from which to take name of section. This is always 1 unless the section-starting regular expression has more than one explicit group. Note that using 1 instead of 0 means that an explicit group using parentheses is required. A string can be used if the groups have names in the regular expression reg.

begin: {True} | False

Whether section regular expression must begin line

endreg: {None} | str

Optional regular expression for end of section. If used, some lines will end up in sections called "_inter1", "_inter2", etc.

endbegin: {begin} | True | False

Whether section-end regular expression must begin line

endngr: {ngr} | int | str

Group number of name for title of end-of-section regex

Effects:
fc.SectionNames: list

List of section names is created (includes “_header”)

fc.Section: dict

Dictionary of section line lists is created

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2024-01-02 @ddalle: v1.1; updates after testing

SplitToSections(reg='\\$__([\\w_]+)', ngr=1, begin=True)

Split into sections based on starting regular expression

Call:
>>> fc.SplitToSections()
>>> fc.SplitToSections(reg="\$__([\w_]+)", ngr=1, **kw)
Inputs:
fc: cape.filecntl.FileCntl

File control instance

reg: {"\$__([\w_]+)"} | str

Regular expression for recognizing the start of a new section. By default this looks for sections that start with "$__" as in Cart3D input.cntl files. The regular expression must also include a group (meaning content between parentheses) to capture the name of the section. Thus the default value of "\$__([\w_]+)" finds any name that consists of word characters and/or underscores.

ngr: {1} | int | str

Group number from which to take name of section. This is always 1 unless the section-starting regular expression has more than one explicit group. Note that using 1 instead of 0 means that an explicit group using parentheses is required. A string can be used if the groups have names in the regular expression reg.

begin: {True} | False

Whether section regular expression must begin line

endreg: {None} | str

Optional regular expression for end of section. If used, some lines will end up in sections called "_inter1", "_inter2", etc.

Effects:
fc.SectionNames: list

List of section names is created (includes “_header”)

fc.Section: dict

Dictionary of section line lists is created

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2024-01-02 @ddalle: v1.1; save regex used

UpdateLines()

Update the global file text from current section content

Call:
>>> fc.UpdateLines()
Inputs:
fc: cape.filecntl.FileCntl

File control instance

Effects:
fc.lines: list

Lines are rewritten to match the sequence of lines from the sections

Versions:
  • 2014-06-03 @ddalle: v1.0

UpdateSections()

Remake the section split if necessary

This runs SplitToSections() is run if fc._updated_lines is True.

Call:
>>> fc.UpdateSections()
Inputs:
fc: cape.filecntl.FileCntl

File control instance

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2024-01-02 @ddalle: v1.1; fix for generic sec regex

Write(fname=None)

Write to text file

Call:
>>> fc.Write()
>>> fc.Write(fname)
Inputs:
fc: cape.filecntl.FileCntl

File control instance, defaults to fc.fname

fname: str

Name of file to write to

Versions:
  • 2014-06-03 @ddalle: v1.0

  • 2015-11-16 @ddalle: v1.1; use _Write()

WriteEx(fname=None)

Write to text file as an executable script

Call:
>>> fc.WriteEx()
>>> fc.WriteEx(fname)
Inputs:
fc: cape.filecntl.FileCntl

File control instance, defaults to fc.fname

fname: str

Name of file to write to

Versions:
  • 2014-06-23 @ddalle: v1.0

  • 2024-01-02 @ddalle: v1.1
    • remove two ‘if’ statements using bit-shift

    • test if Windows