Python:如何解析“返回”字符串

时间:2015-03-20 13:45:51

标签: python parsing

我正在编写一个通过导入使用现有框架的小工具。

我正在使用的部分是:

def exec_command(self, command, timeout=60, mode=cli.CLIMode.UNDEF,
                     output_expected=None, error_expected=False, prompt=None):
        """Executes the given command.

        This method handles detecting simple boolean conditions such as
        the presence of output or errors.

        :param command:  command to execute, newline appended automatically
        :param timeout:  maximum time, in seconds, to wait for the command to
            finish. 0 to wait forever.
        :param mode:  mode to enter before running the command. The default
            is :func:`default_mode`.  To skip this step and execute directly
            in the cli's current mode, explicitly set this parameter to None.
        :param output_expected: If not None, indicates whether output is
            expected (True) or no output is expected (False).
            If the opposite occurs, raise UnexpectedOutput. Default is None.
        :type output_expected: bool or None
        :param error_expected: If true, cli error output (with a leading '%')
            is expected and will be returned as regular output instead of
            raising a CLIError.  Default is False, and error_expected always
            overrides output_expected.
        :type error_expected: bool
        :param prompt: Prompt regex for matching unusual prompts.  This should
            almost never be used as the ``mode`` parameter automatically
            handles all typical cases.  This parameter is for unusual
            situations like the install config wizard.

        :return: output of the command, minus the command itself.

        :raises CmdlineTimeout: on timeout
        :raises CLIError: if the output matches the cli's error format, and
            error output was not expected.
        :raises UnexpectedOutput: if output occurs when no output was
            expected, or no output occurs when output was expected
        """

        if output_expected is not None and type(output_expected) is not bool:
            raise TypeError("exec_command: output_expected requires a boolean "
                            "value or None")

        if mode is cli.CLIMode.UNDEF:
            mode = self.default_mode
        if mode is not None:
            self.enter_mode(mode)

        self._log.debug('Executing cmd "%s"' % command)

        if prompt is None:
            prompt = self._prompt
        (output, match_res) = self._send_line_and_wait(command,
                                                       prompt,
                                                       timeout=timeout)

        # CLI adds on escape chars and such sometimes and the result is that
        # some part of the command that was entered shows up as an extra
        # initial line of output.  Strip off that initial line.
        output = '\n'.join(output.splitlines()[1:])

        if output and (re.match(self.CLI_ERROR_PROMPT, output)):
            if error_expected:
                # Skip output_expected processing entirely.
                return output
            else:
                try:
                    mode = self.current_cli_mode()
                except exceptions.UnknownCLIMode:
                    mode = '<unrecognized>'
                raise exceptions.CLIError(command, output=output, mode=mode)

        if ((output_expected is not None) and (bool(output) !=
                                               bool(output_expected))):
            raise exceptions.UnexpectedOutput(command=command,
                                              output=output,
                                              expected_output=output_expected)
        return output

我在我的剧本中使用:

print sh.cli.exec_command(command, mode="enable")

这完全没问题。该工具正在登录设备,执行命令。根据框架,它的“返回”是“:return:命令的输出,减去命令本身。”这也很好,当命令执行时,我得到:

Generated dump sysdump-csh-20150320-140445.tgz

完美! 对于下一步,我需要创建转储的名称,即没有“生成转储”文本的返回字符串。

现在我正在努力将其解析为一个我可以使用的新变量,例如下载生成的转储并在​​之后删除它等。

2 个答案:

答案 0 :(得分:6)

s = "Generated dump sysdump-csh-20150320-140445.tgz"
print s.split()[-1]

产量

"sysdump-csh-20150320-140445.tgz"

这只是通过拆分空格来解析。每个解析决策都取决于一些假设。这个假设取决于您想要的文件名是连续的(没有内部空格),以及空白拆分列表中的最后一项。

Martijn Pieters打败了我改进的配方:

s.split(None, 2)[-1]

甚至更好:

s.strip().split(None, 2)[-1]

这是最好的,因为它也不假设文件名是连续的。 .strip()也删除了没有尾随空格的假设。

请记住,无论您选择何种简单的解析策略,它始终都依赖于假设。例如,即使使用改进的配方,我们仍然假设文件名是该行的最后一项。如果生成此行的程序更新为"Generated dump sysdump-csh-20150320-140445.tgz on March 20, 2015.",那么我们必须以另一种方式对其进行操作。

答案 1 :(得分:6)

您可以使用字符串切片来获取没有Generated dump部分的部分:

dump_name = return_value[15:]

其中15是文本Generated dump加上空格的长度。

其他选项包括拆分空格;但要注意只分开前两个空格:

dump_name = return_value.split(None, 2)[-1]

任意空格上拆分2次;如果单词之间有1或10个空格,那将无关紧要。或者制表符,换行符,不间断空格等,然后选择结果列表的最后一个元素。