在Python中使用awk在文件中插入文本

在Python中使用awk在文件中插入文本,python,python-3.x,awk,insert,Python,Python 3.x,Awk,Insert,我在使用Python插入一些文本时遇到一些问题。我有一个文件,Package.swift,包含以下内容: targets: [ .target( name: "LibCore", path: "lib/core/" ), .target( name: "LibAppData", dependencies: ["LibCore"], path: "lib/appdata/", swiftSettin

我在使用Python插入一些文本时遇到一些问题。我有一个文件,
Package.swift
,包含以下内容:

  targets: [
    .target(
      name: "LibCore",
      path: "lib/core/"
    ),
    .target(
      name: "LibAppData",
      dependencies: ["LibCore"],
      path: "lib/appdata/",
      swiftSettings: [.define("appdata")]
    ),
我想在开头的
目标:[

这在zsh中使用
awk

    awk '{print} /\.target\(/ && !n {print "      name: \"{full_name}\",\n      dependencies: \[\"LibCore\"\],\n      path: \"lib\/{short_name}\/\",\n      swiftSettings: [.define(\"{short_name}\")]\n    ),\n    .target("; n++}' Package.swift > Package-new.swift && mv Package-new.swift Package.swift
我在Python中尝试了以下内容:

  • 我也尝试过许多变体,试图避开{},但每次我尝试运行脚本时都会遇到
    SyntaxError:invalid syntax

  • 在1中,您遗漏了几个需要转义的双引号字符
  • 这一行在Python中的语法看起来不错,但是在Python中运行awk总是有点恶心。然而,这是awk中的语法错误。与其他一些语言不同,Python中的单引号字符串仍然将转义字符视为转义字符,因此,例如,
    ”\“
    是相同的字符串文字

    这意味着这个例子:
    “name:\“{full\u name}\”
    被转换为
    “name:{full\u name}”“
    ,这会在输入awk时弄乱您的报价

  • 有了这个,你走得太远了:太多的逃避

    这:
    line=line.replace(“\\.target\\(”,
    从不匹配,因为您的文件不包含字符串:
    \.target\(

    这不是一个语法错误,但是,它不会做任何事情

  • 正如他们所说,现在您有两个问题。或者,实际上,有三个问题。您的正则表达式与(3)中的问题相同,
    match()
    是这里使用的错误调用,并且
    string.format
    不是这样工作的

    当重新包尝试使用mis转义正则表达式时,该正则表达式会出现以下错误:

    re.error:missing),位置XX处未终止的子模式
    (其中XX是行号)

    如果从正则表达式中删除多余的转义,则会得到以下结果:
    \.target\(
    。如果
    Package.swift
    文件没有缩进,您可以这样做,但它确实有缩进,并且
    re.match
    函数仅在模式从字符串的开头匹配时才获得匹配。您希望
    re.search
    在任何地方匹配。或者,您可以更改模式rn以匹配
    .target
    字符串前面的任意数量的空白字符,如下所示:
    [\t]*\.target\(

    所以,最后一个问题是:f-strings从它们所在的作用域中引入变量,但是
    string.format
    没有:每个值都需要作为字典的值传入,而您在这里指定的
    l=line
    没有任何作用?除此之外,因为您替换了
    .target(
    string)您的输出文件不是修改或重写它,而是在语法上无效

  • 在这里的一些案例中,我觉得你错过了图书馆电话文档的重要部分?如果你正在做其他事情


    此外,您应该从这些代码段中看到的错误消息完全不同(在一种情况下,根本没有错误)。如果您更改了这么多,并且看到的错误消息没有完全不同,那么问题不在这部分代码中。

    如果您使用的是f-strings,请确保您使用的Python版本支持f-strings。这是3.6或更高版本。谢谢@Aesin!我在脚本中还有一些使用f-strings的其他命令正在运行,因此我认为nk对goDo很好您需要使用
    awk
    ,还是欢迎其他解决方案?当然欢迎其他解决方案,只要我可以在脚本中包括:)@christinam甚至认为这是一个Swift包清单,你必须用Python来做吗?谢谢@Aesin,我已经尝试了你提到的所有更正,但仍然没有成功。介意发布一段你认为应该是的代码片段吗?
    subprocess.call([f"awk '{print} /\\.target\\(/ && !n {{print "      name: "{full_name}\",\n      dependencies: \\[\"LibCore\"\\],\n      path: \"lib\\/{short_name}\\/\",\n      swiftSettings: [.define(\"{short_name}\")]\n    ),\n    .target("; n++ "}}' Package.swift > Package-new.swift && mv Package-new.swift Package.swift"], shell=True) 
    
    subprocess.call(['awk.exe', '{print} /\\.target\\(/ && !n {print "      name: \"{full_name}\",\n      dependencies: \\[\"LibCore\"\\],\n      path: \"lib\\/{short_name}\\/\",\n      swiftSettings: [.define(\"{short_name}\")]\n    ),\n    .target("; n++}', 'Package.swift'])
    
        tmp=tempfile.mkstemp()
        with open("Package.swift") as fd1, open(tmp[1],'w') as fd2:
            for line in fd1:
                line = line.replace("\\.target\\(",f"      name: \"{full_name}\",\n      dependencies: \\[\"LibCore\"\\],\n      path: \"lib\\/{short_name}\\/\",\n      swiftSettings: [.define(\"{short_name}\")]\n    ),\n    .target(")
                fd2.write(line)
        os.rename(tmp[1],"Package.swift")
    
        newtext = '''\
                name: "{full_name}\",\n      dependencies: \\[\"LibCore\"\\],\n      path: \"lib\\/{short_name}\\/\",\n      swiftSettings: [.define(\"{short_name}\")]\n    ),\n    .target(
                '''
        filename = 'Package.swift'
        for line in fileinput.input([filename], inplace=True, backup='.bak'):
            if re.match(r'\\.target\\(', line):
                sys.stdout.write(newtext.format(l=line))
            else:
                sys.stdout.write(line)