python - 在 Python 中使用 awk 在文件中插入文本
问题描述
我在使用 Python 插入一些文本时遇到了一些麻烦。我有一个文件,Package.swift
内容如下:
targets: [
.target(
name: "LibCore",
path: "lib/core/"
),
.target(
name: "LibAppData",
dependencies: ["LibCore"],
path: "lib/appdata/",
swiftSettings: [.define("appdata")]
),
我想.target()
在开口下方插入一个新的targets: [
这awk
在 zsh 中使用:
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 中尝试过以下操作:
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)
我还尝试了许多变体,试图逃避 {},但每次 SyntaxError: invalid syntax
我尝试运行脚本时仍然得到一个。如果不是很明显,Python 不是我的第一语言
有人会知道我错过了什么吗?
谢谢!
解决方案
问题:
- 在 1 中,您错过了几个
"
需要转义的双引号字符。 这条线在 Python 中似乎在语法上很好,但在Python中运行 awk 总是有点恶心。但是,这是awk中的语法错误。与其他一些语言不同,Python 中的单引号字符串仍然将转义字符视为转义字符,因此,例如,
'"'
和'\"'
是相同的字符串文字。这意味着这个例子:
"name: \"{full_name}\""
被转换为"name: "{full_name}""
当喂给 awk 时会扰乱你的引用。有了这个,你就走得太远了:太多的逃避。
This:
line = line.replace("\\.target\\(",
从不匹配,因为您的文件不包含字符串:\.target\(
。不过,这不是语法错误,它不会做任何事情。
正如他们所说,现在你有两个问题。或者,实际上,三个问题。您的正则表达式与 (3) 中存在相同的问题,
match()
是在此处使用的错误调用,并且string.format
不能像那样工作。当 re 包尝试使用它时,错误转义的正则表达式应该给你这个错误:
re.error: missing ), unterminated subpattern at position XX
(其中 XX 是行号)如果您从正则表达式中删除多余的转义,您会得到:
\.target\(
. 如果Package.swift
文件没有缩进,你可以这样做,但它确实有缩进,并且只有当模式从字符串的开头re.match
匹配时,函数才会得到匹配。您想要, 匹配任何地方。或者,您可以更改模式以匹配字符串前任意数量的空白字符,如下所示:re.search
.target
[ \t]*\.target\(
所以,最后一个问题:f-strings 从它们所在的范围中拉入变量,但
string.format
没有:每个值都需要作为字典的值传入,而l=line
您在此处指定的...不什么都不做?最重要的是,因为您替换了.target(
字符串而不是更改或重写它,所以您的输出文件在语法上不是有效的 Swift。
在某些情况下,我觉得您错过了有关您进行的库调用的文档的重要部分?如果您正在处理其他问题,Python 官方文档很好,而且很有帮助!
此外,您应该从这些片段中看到的错误消息完全不同(在一种情况下,根本没有错误)。如果您更改了这么多并且您看到的错误消息并没有完全不同,那么问题不在这部分代码中。
推荐阅读
- string - 如何覆盖 TypeScript 类型别名的 VSCode 工具提示?
- r - 从 R 中的 ga 类中提取 bestSol 为 NULL
- javascript - Mongodb 投影->localhost 和生产部署上的不同属性
- c++ - 如何将字符串流拆分为具有 2 种分隔符(空格和引号)的向量
- sql - COUNT(1) 的不同方法
- vmware-clarity - vmware 清晰度控件周围的黑色边框
- python-3.x - curl -x 的 python 等价物是什么
- solr - 适用于 Windows 10 的 Apache Solr 命令行参考
- c# - 引用程序集或 dll 是否应该复制到部署目录中?
- c++ - 如何在捕获 lambda 参数时使用模板化 typedef?