使用 stdin 的处理输出作为 Sed 中的替换字符串

使用 stdin 的处理输出作为 Sed 中的替换字符串

以下命令给出了我想要的输出:

$ sed '/^<template.*>/,/<\/template>/!d;//d' src/components/**/*.vue | html2jade

因为它将每个包含 html 的模板处理成它的 pug 等效项。

现在是否可以用现在处理后的输出以某种方式替换所有这些文件中最初找到的 html?模板标签之外还有一些其他内容,应该保持原样,即 somescriptstyle标签。

答案1

我相信你不能用 来做到这一点sed。这应该是可能的,awk但很难。 python3似乎更合适。

import re
import subprocess
from io import StringIO
from traceback import format_exception_only

PROCESS_COMMAND = ("html2jade",)
TEMPLATE_OPEN_REGEX = re.compile(r"^<template.*>$")
TEMPLATE_CLOSE_REGEX = re.compile(r"^</template>$")

def replace_templates(file_path) :
    out_buffer = StringIO()
    template_buffer = StringIO()

    with open(file_path, "r") as file :
        lines_gen = enumerate(file, 1)
        for (lineno, line) in lines_gen :
            out_buffer.write(line)

            if (TEMPLATE_OPEN_REGEX.match(line)) :
                for (lineno, line) in lines_gen :
                    if (TEMPLATE_OPEN_REGEX.match(line)) :
                        raise ValueError("nested opening tag on line {:d}".format(lineno))
                    elif (TEMPLATE_CLOSE_REGEX.match(line)) :
                        break

                    template_buffer.write(line)
                else :
                    raise ValueError("tag never closed")

                proc = subprocess.run(
                    PROCESS_COMMAND,
                    input=template_buffer.getvalue(),
                    stdout=subprocess.PIPE,
                    stderr=subprocess.DEVNULL,
                    encoding="UTF-8",
                    check=True)

                out_buffer.write(proc.stdout)
                out_buffer.write(line)

                template_buffer.seek(0)
                template_buffer.truncate()
            elif (TEMPLATE_CLOSE_REGEX.match(line)) :
                raise ValueError("closing tag encountered on line {:d}, before opening tag".format(lineno))

    with open(file_path, "w") as file :
        file.write(out_buffer.getvalue())

def main(args) :
    for a in args :
        try :
            replace_templates(a)
        except Exception as ex :
            print("generation failed for file {!r} ({:s})".format(
                 a,
                 format_exception_only(type(ex), ex)[-1].rstrip()))
        else :
            print("file {!r} written".format(a))

if (__name__ == "__main__") :
    from sys import argv

    main(argv[1:])
  • 您似乎忽略了标记行上的任何模板代码,因此我的代码不处理此问题并进行全行匹配。
  • 值错误如果开始和结束模板标签的顺序不正确,则会引发该错误。
  • 文件未找到错误被提出,如果.vue未找到文件或子进程命令。
  • 子进程.CalledProcessError如果子进程不返回 0,则会引发该异常。
  • Unicode解码错误如果子进程输出非 UTF-8 字符,则会引发该错误。
  • 如果发生错误,则不会触及该文件。
  • 完整的文件输出缓冲到 RAM 中。

相关内容