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

2024-09-30 18:31:13 发布

您现在位置:Python中文网/ 问答频道 /正文

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

  targets: [
    .target(
      name: "LibCore",
      path: "lib/core/"
    ),
    .target(
      name: "LibAppData",
      dependencies: ["LibCore"],
      path: "lib/appdata/",
      swiftSettings: [.define("appdata")]
    ),

我想在开口targets: [的正下方插入一个新的.target()

这在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中尝试了以下内容:

  1. 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) 
    
  2. 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'])
    
  3.     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")
    
  4.     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)
    

我还尝试了许多变体,试图避开{},但每次我尝试运行脚本时都会得到一个{}。如果不是很明显,Python不是我的第一语言🙈

有人知道我错过了什么吗

谢谢大家!


Tags: pathnamepackagetargetliblinedependenciesfull
1条回答
网友
1楼 · 发布于 2024-09-30 18:31:13

问题是:

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

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

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

    此:line = line.replace("\\.target\\(",从不匹配,因为您的文件不包含以下字符串:\.target\(

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

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

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

    re.error: missing ), unterminated subpattern at position XX(其中XX是行号)

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

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

在这里的一些情况下,我觉得您错过了您所做的库调用文档的重要部分?如果你在做别的事情,the official Python documentation is good, and pretty helpful!

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

相关问题 更多 >