如何使用输入和输出作为同一文件运行sed命令?

Arv*_*ran 49 sed

我正在尝试在shell脚本中使用sed命令,我想删除读取的STARTremoveThisComment行和读取的行removeThisCommentEND.

我可以在使用时将其复制到新文件时执行此操作

sed 's/STARTremoveThisComment//' > test
Run Code Online (Sandbox Code Playgroud)

但是如何通过使用相同的文件作为输入和输出来做到这一点?

pax*_*blo 83

sed -i(或扩展版本--in-place)将自动执行通常使用较低级实现完成的过程,即将输出发送到临时文件,然后将其重命名为原始文件.

-i是就地编辑,你也可以保持原有的副本提供一个备份文件的后缀:

sed -i.bak fileToChange
sed --in-place=.bak fileToChange
Run Code Online (Sandbox Code Playgroud)

这两个都将保留原始文件fileToChange.bak.

请记住,在就地编辑可能无法在所有可用的sed实现,但它在GNU sed这应该是在Linux上使用的所有变体,按你的标签.

如果您使用的是更原始的实现,则可以使用以下内容:

sed 'whatever' oldfile >newfile ; mv newfile oldfile
Run Code Online (Sandbox Code Playgroud)

虽然更多的错误检查会很好.

  • 请注意,对于Mac,您必须为备份文件添加参数.所以sed -i'.bak'会起作用.如果你不想要文件的两个副本,你可以传递一个空白的parm:sed -i'' (4认同)

小智 10

您可以使用标志-i进行就地编辑,使用-e标记正常的脚本表达式:

sed -i -e 's/pattern_to_search/text_to_replace/' file.txt
Run Code Online (Sandbox Code Playgroud)

要删除与特定模式匹配的行,可以使用更简单的语法.注意d标志:

sed -i '/pattern_to_search/d' file.txt
Run Code Online (Sandbox Code Playgroud)


Wil*_*ell 5

你真的不应该使用sed.这个问题似乎经常出现,并且看起来非常奇怪,因为一般的解决方案是如此微不足道,人们想要知道如何在sed,python和ruby等中做到这一点似乎很奇怪.如果要对输入进行过滤操作并覆盖它,请使用以下简单脚本:

#!/bin/sh -e
in=${1?No input file specified}
mv $in ${bak=.$in.bak}
shift
"$@" < $bak > $in
Run Code Online (Sandbox Code Playgroud)

将它放在您的路径中的可执行文件名中inline,然后问题就解决了.例如:

inline input-file sed -e s/foo/bar/g
Run Code Online (Sandbox Code Playgroud)

现在,如果要添加逻辑以保留多个备份,或者如果您有一些选项可以更改备份命名方案,或者其他任何选项,则可以在一个位置进行修复.在使用perl?处理文件时,在备份文件上获取1-up计数器的命令行选项是什么?怎么样ruby?这个选项有gnu-sed什么不同吗?如何awk处理?unix的全部意义在于工具只做一件事.处理备份文件的逻辑是第二件事,需要将其考虑在内.如果要实现工具,请不要添加逻辑来创建备份文件.告诉您的用户使用第二个工具.整合很糟糕.模块化很好.这是unix的方式.

请注意,此脚本有几个问题.例如,可以改变输入文件的许可/模式.我确定还有无数其他问题.但是,通过将备份逻辑放在包装器脚本中,您可以本地化所有这些问题,而不必担心sed覆盖文件和更改模式,同时python保持文件到位并且不会更改inode(我编写了这些两种情况,关键是并非所有工具都使用相同的逻辑,而包装脚本将会.)

  • 我不同意,如果`sed`有功能去做,那么我认为没有理由不去做.它似乎也适合他想要的东西. (3认同)
  • 因此,如果您只计划使用GNU实现,那么请使用它.如果您运行多个平台,那么您很可能意识到差异.据我所知,如果你使用的是Mac OS X的Linux,它们都有`sed`和`-i`标志.我也检查过,FreeBSD也有这个功能. (2认同)