docs: def ParseCmd(self, cmd_input, attributes=None, templates=None):
          """Creates a TextTable table of values from cmd_input string.
      Parses command output with template/s. If more than one template is found
      subsequent tables are merged if keys match (dropped otherwise).
      Args:
        cmd_input: String, Device/command response.
        attributes: Dict, attribute that further refine matching template.
        templates: String list of templates to parse with. If None, uses index
      Raises:
        CliTableError: A template was not found for the given command.
      """
          # Store raw command data within the object.
          self.raw = cmd_input
  
          if not templates:
              # Find template in template index.
              row_idx = self.index.GetRowMatch(attributes)
              if row_idx:
                  templates = self.index.index[row_idx]["Template"]
              else:
                  raise CliTableError(
                      'No template found for attributes: "%s"' % attributes
                  )
  
          template_files = self._TemplateNamesToFiles(templates)
  
          try:
              # Re-initialise the table.
              self.Reset()
              self._keys = set()
              self.table = self._ParseCmdItem(self.raw, template_file=template_files[0])
  
              # Add additional columns from any additional tables.
              for tmplt in template_files[1:]:
                  self.extend(
                      self._ParseCmdItem(self.raw, template_file=tmplt), set(self._keys)
                  )
          finally:
              for f in template_files:
                  f.close()