unix - sed单词 - sed开头



sed编辑文件到位 (9)

我试图找出是否可以在单个sed命令中编辑文件,而无需手动将编辑的内容流式传输到新文件中,然后将新文件重命名为原始文件名。 我尝试了-i选项,但是我的Solaris系统表示-i是非法的选项。 有不同的方法吗?

https://src-bin.com


Answer #1

如果您要更换相同数量的字符,并仔细阅读“就地”编辑文件后 ...

您也可以使用重定向操作符<>来打开文件以读取和写入:

sed 's/foo/bar/g' file 1<> file

现场观看:

$ cat file
hello
i am here                           # see "here"
$ sed 's/here/away/' file 1<> file  # Run the `sed` command
$ cat file
hello
i am away                           # this line is changed now

Bash参考手册→3.6.10打开用于读写的文件描述符

重定向操作符

[n]<>word

导致名称为扩展名的文件在文件描述符n上读取和写入,如果未指定n,则在文件描述符0上打开。 如果该文件不存在,则会创建该文件。


Answer #2

sed支持就地编辑。 从man sed

-i[SUFFIX], --in-place[=SUFFIX]

    edit files in place (makes backup if extension supplied)

示例

假设你有一个带有文本的文件hello.txt

hello world!

如果您想保留旧文件的备份,请使用:

sed -i.bak 's/hello/bonjour' hello.txt

你将会得到两个文件: hello.txt和内容:

bonjour world!

以及带有旧内容的hello.txt.bak

如果您不想保留副本,只是不要传递扩展参数。


Answer #3

以下工作正常我的Mac

sed -i.bak 's/foo/bar/g' sample

我们正在用示例文件中的bar替换foo。 原始文件的备份将保存在sample.bak中

对于没有备份的内联编辑,请使用以下命令

sed -i'' 's/foo/bar/g' sample

Answer #4

你可以使用vi

vi -c '%s/foo/bar/g' my.txt -c 'wq'

Answer #5

sed没有编辑文件的系统上,我认为更好的解决方案是使用perl

perl -pi -e 's/foo/bar/g' file.txt

尽管这确实会创建一个临时文件,但由于提供了空置的后缀/扩展名,它将替换原始文件。


Answer #6

就像Moneypenny在Skyfall中说的那样:“有时候旧的方式是最好的。” Kincade稍后说了类似的话。

$ printf',s / false / true / g \ nw \ n'| ed {YourFileHere}

快速编辑到位。 添加'\ nw \ n'来写入文件。 对延迟应答请求抱歉。


Answer #7

有一点需要注意, sed不能单独编写文件,因为sed的唯一目的是充当“流”(即stdin,stdout,stderr和其他>&n缓冲区,套接字等的管道)的编辑器, 。 考虑到这一点,您可以使用另一个命令tee将输出写回文件。 另一种选择是通过将内容传送到diff来创建补丁。

三通法

sed '/regex/' <file> | tee <file>

补丁方法

sed '/regex/' <file> | diff -p <file> /dev/stdin | patch

更新:

此外,请注意,修补程序将从diff输出的第1行中获得文件更改:

修补程序不需要知道要访问哪个文件,因为它位于diff输出的第一行:

$ echo foobar | tee fubar

$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin
*** fubar   2014-03-15 18:06:09.000000000 -0500
--- /dev/stdin  2014-03-15 18:06:41.000000000 -0500
***************
*** 1 ****
! foobar
--- 1 ----
! fubar

$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin | patch
patching file fubar

Answer #8

sed来做你想做的事是不可能的。 甚至支持用于编辑文件的-i选项的sed版本也完全符合您明确声明不需要的内容:它们写入临时文件,然后重命名文件。 但也许你可以使用ed 。 例如,要将文件file.txt所有出现的foo更改为bar ,您可以执行以下操作:

echo ',s/foo/bar/g; w' | tr \; '\012' | ed -s file.txt

语法与sed类似,但肯定不完全相同。

但是也许你应该考虑为什么你不想使用重命名的临时文件。 即使您没有-i支持sed ,您也可以轻松编写脚本来为您完成工作。 您可以使用inline file sed 's/foo/bar/g'代替sed -i 's/foo/bar/g' file 。 这样的脚本是微不足道的写作。 例如:

#!/bin/sh -e
IN=$1
shift
trap 'rm -f $tmp' 0
tmp=$( mktemp )
<$IN "[email protected]" >$tmp && cat $tmp > $IN  # preserve hard links

应该足够用于大多数用途。


Answer #9
mv file.txt file.tmp && sed 's/foo/bar/g' < file.tmp > file.txt

应该保留所有的硬链接,因为输出被引导回覆盖原始文件的内容,并且避免需要特殊版本的sed。





solaris