【问题标题】:Using awk in Python to insert text in a file在 Python 中使用 awk 在文件中插入文本
【发布时间】:2020-06-19 17:14:16
【问题描述】:

我在使用 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)
    

我也尝试了许多变体以逃避 {},但每次我尝试运行脚本时仍然收到 SyntaxError: invalid syntax。如果不是很明显,Python 不是我的第一语言????

有人知道我错过了什么吗?

谢谢!

【问题讨论】:

  • 如果您使用的是 f-strings,请确保您使用的是支持 f-strings 的 Python 版本。那是 3.6 或更高。
  • 感谢@Aesin!我在脚本中有一些使用 f 字符串的其他命令正在运行,所以我觉得很好
  • 需要使用awk,还是欢迎其他解决方案?
  • 当然欢迎其他解决方案,只要我可以包含在脚本中 :)
  • @christinam 甚至认为这是一个 Swift 包清单,你必须在 Python 中这样做吗?

标签: python python-3.x awk insert


【解决方案1】:

问题:

  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 不能那样工作。

    当 re 包尝试使用它时,错误转义的正则表达式应该给你这个错误:

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

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

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

在某些情况下,我觉得您错过了有关您进行的库调用的文档的重要部分?如果您正在处理其他事情,the official Python documentation is good, and pretty helpful!

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

【讨论】:

  • 谢谢@Aesin,我已经尝试了你提到的所有更正,但仍然没有成功。介意发布您认为应该的代码 sn-p 吗?
猜你喜欢
  • 2022-08-02
  • 1970-01-01
  • 2014-04-25
  • 1970-01-01
  • 2021-08-21
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 2018-09-03
相关资源
最近更新 更多