无法使用 SED 快速编辑文件

Posted

技术标签:

【中文标题】无法使用 SED 快速编辑文件【英文标题】:Unable to use SED to edit files fast 【发布时间】: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 编辑文件而不给我一个空文件?

【问题讨论】:

【参考方案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 上不存在

以上是关于无法使用 SED 快速编辑文件的主要内容,如果未能解决你的问题,请参考以下文章

sed 命令无法在 yaml 文件中查找和替换内容?

将 SED 与新行一起使用

Shell 基础 -- 流编辑器 sed 详解

Java File Watcher 无法识别文件更改

使用 root 用户通过 SSH 上传,无法在 cPanel 中编辑文件

解决ssh远程执行命令无法使用awk/sed的问题