无法使用 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。
在您的情况下,执行管道是一个两阶段的过程:首先构建管道,然后运行它。 >
表示“打开文件,截断它,并将其连接到文件描述符 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 快速编辑文件的主要内容,如果未能解决你的问题,请参考以下文章