【问题标题】:Python string literals, regex and sedPython 字符串文字、正则表达式和 sed
【发布时间】:2016-07-05 10:39:31
【问题描述】:

我是 Python 新手。

我正在使用 python 脚本将一系列文件导入 sqlite3 数据库。一些原始文件包含虚假的^M 字符,将记录分成多行。

以下 sed 命令正确删除了 ^M 并将这两行连接起来,创建了一条有效记录。

sed -i '/^M^M$/ {s/^M//g;N;s/\n//};' <file>

上面的^M 是用CTRL+V CTRL+M 序列创建的。

sed 调用的 Python 行是:

cmd = "sed -i '/\^M\^M$/ {s/\^M//g; N; s/\n////g; };' %s" % (file)
os.system(cmd)

我在 Python 中尝试了各种转义序列(包括三个''')并得到解析错误,包括 unterminated address regexunterminated 's' commandunknown option to 's',并且没有转义 ^M 我很难-停止SyntaxError: EOL while scanning string literal的解析错误

我该怎么做

a) 对 sed 调用进行编码,以便在使用 os.system(cmd) 调用时正确执行

b) 直接在 python 中执行等效替换(可能更可取,但我希望能够一次执行多种类型的校正,而不是每种校正类型一次)。

谢谢。

【问题讨论】:

  • 通常强烈建议使用subprocess 模块而不是os.system 来调用外部二进制文件。 stackoverflow.com/questions/6706953/…有一些很好的例子
  • 另外,您似乎正在为每个文件创建一个新的sed? @holdenweb 的解决方案可能会比这样做更好,但是如果您有“大量”文件,那么优化您的 sed 调用并且只分叉一个可能是最好的解决方案。如果您担心速度,可能都值得测试?
  • @HumphreyTriscuit 是的。我从一个文件开始,但计划在我开始工作后将它组合成一个调用。婴儿步。 ;) 现在我正在尝试改变holdenweb 的建议,看看我是否可以在没有产卵的情况下让它工作。它只有几百万条记录和大约 30 个文件,但我希望它相当高效。
  • 太棒了。我一定很想知道哪一个对你来说更快! :)

标签: python regex sed


【解决方案1】:

^M 字符是Carriage Return (CR)。这是python中的'\r'字符。

所以,我想,这应该可以正常工作:

cmd = "sed -i '/\r\r$/ {s/\r//g; N; s/\\n////g; };' %s" % (file)
os.system(cmd)

【讨论】:

  • cmd = "sed -i '/\r\r$/ {s/\r//g; N; s/\\n//g; };' %s" % (file) 有效。它需要对` in \n` 进行转义。我将继续尝试让原生 python 解决方案发挥作用,但这让我很兴奋。
  • * 为\n 中的\ 转义 无法为这条评论转义! :D
  • 感谢您的 cmets!
【解决方案2】:

完全在 Python 中执行此操作会容易得多,特别是因为您说要执行多个替换。回车符是"\r"

该任务的未测试代码如下:

replacements = (("\r", ""),
                ("one", "two"),
                ("three", "four"))
with open(filename, "r") as fin, open(filename+".new", "w") as fout:
    data = fin.read()
    for t1, t2 in replacements:
        data = data.replace(t1, t2)
    fout.write(data)

然后,读者可以练习重命名输出文件以覆盖输入文件。请注意,顺便说一下,此代码明确设计用于处理文本文件。在 Python 3 中,这会有所作为。

【讨论】:

  • 这部分有效。它删除了^M,但没有加入下一行 [仅当有替换时] 以在行之间拆分时创建有效记录,但其他行保持不变(N; s/\n////g; 部分上面的 sed 命令)。
  • 使用for line in fin: for t1,t2 in replacements: line = line.replace(t1, t2) line.write(data)可以节省内存
  • 确实如此。与许多程序一样,有一些方法可以权衡内存和时间,而且我的解决方案针对时间进行了优化,但它的缺点是它不能用于处理大文件
猜你喜欢
  • 2012-02-21
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
相关资源
最近更新 更多