【问题标题】:subprocess using the sed command to input a variable into a specific line in a unix file使用 sed 命令将变量输入到 unix 文件中的特定行的子进程
【发布时间】:2016-05-23 21:23:22
【问题描述】:

我是一个完整的 Python 新手,但我需要创建一个小脚本作为更大项目的一部分。

我正在尝试使用一个小的 Python 脚本将变量输入到 Unix 文件中的一行代码中。我一直在尝试使用subprocess.call(),它使我能够执行我需要的命令,但不允许我放入变量中。

我一直在尝试以下方法:

import subprocess
var="some_variable"
subprocess.call(['sudo', 'sed', '-i', '-e' 's/line_to_replace.*/replacement_line' + var, /path/to/file.conf])

【问题讨论】:

  • 如果您只想以最好的方式从 Python 中替换文件的单行,为什么要让“使用 sed”成为您问题的一部分?
  • ...特别是,sed-i 参数是非标准功能——纯 POSIX 指定的 sed 根本无法满足您的要求。
  • 另外,您说的是“特定行”,但这不是您的代码所做的:它按内容匹配,而不是按行号匹配;您没有指定该行,这意味着该行...嗯,不是特定的。
  • 你能解释一下脚本是如何无法完成你想要它做的事情的吗?如果您需要以 root 身份运行它,最好从子进程调用中删除“sudo”,而是以 root/sudo 身份运行 python 脚本本身。我不确定句柄子进程在使用 sudo 时是否会处理可能的密码提示。
  • @HåkenLid, subprocess 除非被告知,否则不会更改 stdin/stdout/stderr,因此无需“处理”任何提示;它将直接传递到控制台。 (如果用户没有从带有 TTY 的某个地方运行它——例如,如果这个脚本是由 cron 调用的——许多 sudo 配置将导致它立即失败,但是......好吧,有sudo 有这么多可能的配置方式,以至于潜入那种蜡球并不能很好地利用我们的时间。

标签: python sed subprocess


【解决方案1】:

您的直接问题是sed 语法错误:您在替换字符串末尾缺少结束分隔符(并且需要引用文件名)。然而,大多数简单的 Unix 工具都可以很容易地用纯 Python 替换,通常会立即获得优雅和效率的提升(避免外部进程通常会显着提高性能)。

import fileinput

for line in fileinput('/path/to/file', inline=True):
    if line.startswith('line_to_replace'):
       line = var + '\n'
    print line

如果您真的需要正则表达式支持,那么更改应该是显而易见的。 sudo 更难替换;如果获得对要操作的文件的写入权限并非易事,也许您可​​以简单地从提示符sudo 运行它。

【讨论】:

  • 实际上可能会打开文件以进行输出(或临时文件并执行 mv-to-atomically-replace 舞蹈)以使其完全替代(但正如您所说, sudo)。
【解决方案2】:

这里最明显的失败是您的代码没有在替换值的末尾添加尾随 / 以使其成为有效的 sed 命令:

import subprocess
var="some_variable".replace('/', r'\/') # backslash-escape any sigil instances
subprocess.call(['sudo', 'sed', '-i',
                 '-e', 's/line_to_replace.*/replacement_line%s/' % (var,),
                 '/path/to/file.conf'])

也就是说,请注意这不适用于POSIX-standard sed(没有-i)或BSD sed(sed -i 的扩展参数不是可选的)。用于就地编辑文件的 POSIX 标准工具是 edex;考虑学习它们。

【讨论】:

  • 非常感谢您的快速回复。我现在可以正常工作了。
  • @Gooners 也有多种方法可以仅使用 python 而不是外包给 sed 等。您需要几行额外的代码,但 python 脚本通常更具可读性和更容易调试。
  • 干杯,我先看看 ed 和 ex。
猜你喜欢
  • 2012-02-15
  • 2021-12-23
  • 2018-08-29
  • 1970-01-01
  • 2011-08-31
  • 2019-03-04
  • 1970-01-01
  • 2018-02-28
  • 1970-01-01
相关资源
最近更新 更多