Shell 在文件中查找和替换并覆盖文件';不行,它会清空文件
我想通过命令行对HTML文件运行查找和替换 我的命令如下所示:Shell 在文件中查找和替换并覆盖文件';不行,它会清空文件,shell,unix,sed,io-redirection,Shell,Unix,Sed,Io Redirection,我想通过命令行对HTML文件运行查找和替换 我的命令如下所示: sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html tmp=$(sed 'code' file); echo -n "$tmp" > file 当我运行这个程序,然后查看文件时,它是空的。它删除了我文件的内容 再次还原文件后运行此操作时: sed -e s/STRING_TO_REPLACE/STRING_TO_REPLA
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html
tmp=$(sed 'code' file); echo -n "$tmp" > file
当我运行这个程序,然后查看文件时,它是空的。它删除了我文件的内容
再次还原文件后运行此操作时:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
stdout
是文件的内容,已经执行了查找和替换
为什么会发生这种情况?当shell在命令行中看到
>index.html
时,它会打开文件index.html
,以便写入,删除它以前的所有内容
要解决此问题,您需要将-i
选项传递到sed
,以内联方式进行更改,并在原始文件进行更改之前创建其备份:
sed -i.bak s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
如果没有.bak,该命令将在某些平台上失败,例如Mac OSX。当shell在命令行中看到
>index.html
时,它会打开文件index.html
进行写入,删除所有以前的内容
要解决此问题,您需要将-i
选项传递到sed
,以内联方式进行更改,并在原始文件进行更改之前创建其备份:
sed -i.bak s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
如果没有.bak,该命令将在某些平台上失败,例如Mac OSX。使用sed的-i选项,例如
sed -i bak -e s/STRING_TO_REPLACE/REPLACE_WITH/g index.html
使用sed的-i选项,例如
sed -i bak -e s/STRING_TO_REPLACE/REPLACE_WITH/g index.html
您应该尝试使用选项
-i
进行就地编辑。您应该尝试使用选项-i
进行就地编辑。另一种有用的模式是:
sed -e 'script script' index.html > index.html.tmp && mv index.html.tmp index.html
这在不使用-i
选项的情况下具有大致相同的效果,另外还意味着,如果sed脚本由于某种原因失败,输入文件不会被关闭。此外,如果编辑成功,则不会留下任何备份文件。这种习惯用法在makefile中很有用
相当多的SED都有
-i
选项,但不是所有SED都有;posix sed是一个没有。因此,如果您的目标是可移植性,最好避免使用。另一种有用的模式是:
sed -e 'script script' index.html > index.html.tmp && mv index.html.tmp index.html
这在不使用-i
选项的情况下具有大致相同的效果,另外还意味着,如果sed脚本由于某种原因失败,输入文件不会被关闭。此外,如果编辑成功,则不会留下任何备份文件。这种习惯用法在makefile中很有用
相当多的SED都有
-i
选项,但不是所有SED都有;posix sed是一个没有。因此,如果您的目标是可移植性,最好避免使用。和ed
答案:
printf "%s\n" '1,$s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' w q | ed index.html
为了重申这一点,shell首先处理重定向,清除“input.html”文件,然后调用“sed”命令传递一个现在为空的文件 和
ed
答案:
printf "%s\n" '1,$s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' w q | ed index.html
为了重申这一点,shell首先处理重定向,清除“input.html”文件,然后调用“sed”命令传递一个现在为空的文件 要更改多个文件(并将每个文件的备份保存为*.bak):
将获取目录中的所有文件,并将|
替换为x
这被称为“Perl派”(简单如派)来更改多个文件(并将每个文件的备份保存为*.bak):
将获取目录中的所有文件,并将|
替换为x
这被称为“Perl派”(非常简单)警告:这是一种危险的方法它滥用linux中的i/o缓冲区,并使用特定的缓冲选项来处理小文件。这是一种有趣的好奇心但不要将其用于实际情况强> 除了
sed的-i
选项之外
您可以使用tee
实用程序
从man
:
tee-从标准输入读取并写入标准输出和文件
因此,解决办法是:
sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee | tee index.html
--此处重复tee
,以确保管道得到缓冲。然后,管道中的所有命令都会被阻塞,直到它们获得一些要处理的输入。当上游命令将1个字节缓冲区(大小已定义)写入命令输入时,管道中的每个命令都会启动。因此,最后一个命令tee index.html
,打开文件进行写入并清空文件,在上游管道完成并且输出在管道内的缓冲区中后运行
很可能以下情况不起作用:
sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee index.html
--它将在没有任何阻塞的情况下同时运行管道的两个命令。(在不阻塞的情况下,管道应该逐行而不是逐缓冲区传递字节。与运行cat | sed s/bar/GGG/
时相同。在不阻塞的情况下,它更具交互性,通常只有两个命令的管道在不缓冲和阻塞的情况下运行。缓冲更长的管道。)tee index.html
将打开文件进行写入,文件将被清空。但是,如果始终打开缓冲,第二个版本也会工作。警告:这是一种危险的方法它滥用linux中的i/o缓冲区,并使用特定的缓冲选项来处理小文件。这是一种有趣的好奇心但不要将其用于实际情况强>
sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' index.html
除了sed的-i
选项之外
您可以使用tee
实用程序
从man
:
tee-从标准输入读取并写入标准输出和文件
因此,解决办法是:
sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee | tee index.html
--此处重复tee
,以确保管道得到缓冲。然后,管道中的所有命令都会被阻塞,直到它们获得一些要处理的输入。管道中的每个命令在
sed '30,40 s/version/story/gi' myfile.txt > myfile1.txt
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
less index.html | sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g