【问题标题】:Unable to use SED to edit files fast无法使用 SED 快速编辑文件
【发布时间】:2010-10-17 21:16:13
【问题描述】:

文件最初是

$cat so/app.yaml 
application: SO
...

我运行以下命令。我得到一个空文件。

$sed s/SO/so/ so/app.yaml > so/app.yaml 
$cat so/app.yaml 
$

如何使用 SED 编辑文件而不给我一个空文件?

【问题讨论】:

    标签: sed


    【解决方案1】:
    $ sed -i -e's/SO/so/' so/app.yaml
    

    -i 表示就地。

    【讨论】:

    • 来自手册页:不建议在就地编辑文件时提供零长度扩展名,因为在磁盘空间耗尽等情况下,您可能会面临损坏或部分内容的风险。
    • 谢谢!在过去的三十分钟里,我一直在为此苦苦挣扎。
    • 如果这对您不起作用:您使用的sed 版本可能不支持-i - 例如,在Solaris 中。在这种情况下,通常会有一个gsed 支持它。
    • -i 在 AIX 系统上不受支持。解决方法是将其输出到一个 tmp 文件,然后将其复制到您要修改的文件中。
    【解决方案2】:

    我认为将输出重定向到您正在编辑的同一文件会导致您的问题。

    您需要将标准输出重定向到某个临时文件,并在 sed 完成后用临时文件覆盖原始文件。

    【讨论】:

    • 如何在不将虚拟文件留在文件夹中的情况下以单行方式做到这一点?
    • 嗯,文件夹“/tmp”是用于虚拟文件的。所以它可能是这样的: sed s/SO/so so/app.yaml > /tmp/tmp321 ; mv -f /tmp/tmp321 so/app.yaml
    【解决方案3】:

    管道中使用的> 将在管道全部设置好后(即在命令执行之前)打开输出文件。因此,输入文件在sed 执行之前被截断。这是所有 shell 重定向的问题,而不仅仅是 sed

    Sheldon Young 的回答展示了如何使用就地编辑。

    【讨论】:

    • 看来只有杨的方式了。我尝试以下代码也失败了sed s/ABC/abc/ settings.py> settings.py.
    • 我认为@Rob 建议的> 的使用是将其输出到一个tmp 文件,然后将其复制回来。 sed s/ABC/abc/ settings.py > tmp; cp tmp settings.py
    【解决方案4】:

    您为这项工作使用了错误的工具。 sed 是一个 stream 编辑器(这就是它被称为 sed 的原因),因此它用于对管道中的流进行动态编辑。 ed OTOH 是一个 file 编辑器,它可以做sed 可以做的所有事情,除了它适用于文件而不是流。 (实际上,恰恰相反:ed 是原始实用程序,sed 是一个克隆,可以避免为流创建临时文件。)

    ed 的工作方式与sed 非常相似(因为sed 只是一个克隆),但有一个重要区别:您可以在文件中移动,但不能在流中移动。因此,ed 中的所有命令都带有一个地址参数,该参数告诉 ed, where 在文件中应用该命令。在您的情况下,您希望在文件中应用命令 everywhere,因此地址参数只是 ,,因为 a,b 表示“从行 a 到行 b”和a 的默认值为 1(文件开头),b 的默认值为 $(文件结尾),因此将它们都排除在外意味着“从文件开头到结尾文件”。然后是s(替代),其余的看起来很像sed

    所以,你的sed 命令s/SO/so/ 变成了ed 命令,s/SO/so/

    而且,由于ed 是一个文件编辑器,更准确地说是一个交互式文件编辑器,我们还需要编写 (w) 文件并退出 (q) 编辑器。

    这是它的整体外观:

    ed -- so/app.yaml <<-HERE
        ,s/SO/so/
        w
        q
    HERE
    

    关于类似问题,另请参阅 my answer

    在您的情况下,执行管道是一个两阶段的过程:首先构建管道,然后运行它。 &gt; 表示“打开文件,截断它,并将其连接到文件描述符 1 (stdout)”。 只有这样才是真正运行的管道,即执行了sed,但是此时文件已经被截断了。

    sed 的某些版本还有一个 -i 参数用于文件的就地编辑,这使得 sed 的行为更像 ed,但不建议使用它:首先,它不支持ed 的所有功能,但更重要的是,它是GNU sed 的非标准化专有扩展,不适用于许多非GNU 系统。我已经有一段时间没有使用非 GNU 系统了,但上次我使用了一个,Solaris、OpenBSD、HP-UX 和 IBM AIX sed 都不支持 -i 参数。

    【讨论】:

    • "GNU sed 的专有扩展" @Jörg:你的意思是 GNU 通过出售代码来赚钱?我一直认为任何人都可以免费使用遵循 GNU 许可证的 GNU 软件(即,如果使用 GNU 代码,您需要免费为他人发布您的代码)。
    • 我不是这个意思。英语不是我的第一语言,也许“专有”是错误的词。我的意思是“-i”仅在 GNU sed 中可用,并且不是 POSIX/SUS 标准的一部分,因此 GNU 可以以任何他们想要的方式重新定义“-i”,其他供应商可以实现“-i”无论如何 他们想要...
    • ... 或者根本不实现它。除了 GNU sed 的源代码外,没有定义“-i”的含义。我的大学曾经在他们的服务器上使用 HP-UX,而学生的第一大问题是他们试图使用诸如“sed -i”或“bash”之类的东西,或者他们从他们的...
    • ...Linux 系统,它不起作用,仅仅是因为它们在 HP-UX 上不存在
    猜你喜欢
    • 1970-01-01
    • 2015-02-27
    • 2011-12-17
    • 2011-05-26
    • 2022-07-12
    • 2016-02-19
    • 2012-04-19
    • 1970-01-01
    • 2015-01-12
    相关资源
    最近更新 更多