BBa*_*les 582 unix shell sed io-redirection
我想通过命令行在HTML文件上运行查找和替换.
我的命令看起来像这样:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html
Run Code Online (Sandbox Code Playgroud)
当我运行它并在之后查看该文件时,它是空的.它删除了我的文件的内容.
当我再次恢复文件后运行它:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
Run Code Online (Sandbox Code Playgroud)
这stdout是文件的内容,并且已执行查找和替换.
为什么会这样?
cod*_*ict 893
当shell> index.html在命令行中看到 它打开文件index.html进行写入时,擦除其以前的所有内容.
要解决此问题,您需要传递-i选项以sed进行内联更改并在原始文件执行更改之前创建原始文件的备份:
sed -i.bak s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
Run Code Online (Sandbox Code Playgroud)
如果没有.bak,命令将在某些平台上失败,例如Mac OSX.
Nor*_*ray 206
另一种有用的模式是:
sed -e 'script script' index.html > index.html.tmp && mv index.html.tmp index.html
Run Code Online (Sandbox Code Playgroud)
这有很多相同的效果,不使用该-i选项,另外意味着,如果sed脚本由于某种原因失败,输入文件不会被破坏.此外,如果编辑成功,则没有剩余的备份文件.这种习惯用法在Makefile中很有用.
相当多的seds有-i选择权,但不是全部; posix sed是一个没有的.因此,如果您的目标是可移植性,那么最好避免使用.
Ric*_*aca 90
sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' index.html
Run Code Online (Sandbox Code Playgroud)
这会对文件index.html进行全局就地替换.引用字符串可以防止查询和替换中的空格问题.
Kev*_*vin 57
使用sed的-i选项,例如
sed -i bak -e s/STRING_TO_REPLACE/REPLACE_WITH/g index.html
Run Code Online (Sandbox Code Playgroud)
Ste*_*emo 18
要更改多个文件(并将每个文件的备份保存为*.bak):
perl -p -i -e "s/\|/x/g" *
Run Code Online (Sandbox Code Playgroud)
将在目录中的所有文件,并替换|有x
这就是所谓的"Perl的馅饼"(容易,因为馅饼)
警告:这是一种危险的方法!它滥用了Linux中的I / O缓冲区,并且具有特定的缓冲区选项,因此可以处理小型文件。这是一个有趣的好奇心。但是不要在实际情况下使用它!
除了-i选项之外,sed
您还可以使用该tee实用程序。
来自man:
tee-从标准输入读取并写入标准输出和文件
因此,解决方案将是:
sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee | tee index.html
Run Code Online (Sandbox Code Playgroud)
-在这里tee重复以确保管道被缓冲。然后,管道中的所有命令都将被阻塞,直到它们获得一些可操作的输入为止。当上游命令已将1个字节缓冲区(大小在某处定义)写入命令输入时,管道中的每个命令都会启动。因此,最后一个命令tee index.html(打开文件以写入并清空文件)将在上游管道完成并且输出在管道内的缓冲区中之后运行。
以下情况很可能不起作用:
sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee index.html
Run Code Online (Sandbox Code Playgroud)
-它将同时运行管道的两个命令,而不会发生任何阻塞。(不会阻塞管道应该由缓冲区传递由行而不是缓冲区的字节线。同样,你在运行时的cat | sed s/bar/GGG/。如果没有阻挡它的互动性更强,通常只有2命令的管道没有缓冲和阻挡运行,较长的管道中缓存。)的tee index.html意志打开文件进行写入,它将被清空。但是,如果始终打开缓冲,则第二个版本也将起作用。
sed -i.bak "s#https.*\.com#$pub_url#g" MyHTMLFile.html
Run Code Online (Sandbox Code Playgroud)
如果您要添加链接,请尝试此操作.按上述方式搜索URL(以https开头,此处以..com结尾)并将其替换为URL字符串.我$pub_url在这里使用了一个变量.s这里意味着搜索和g意味着全球替代.
有用 !
命令的问题
sed 'code' file > file
Run Code Online (Sandbox Code Playgroud)
是file在 sed 实际处理它之前被 shell 截断的。结果,您得到一个空文件。
正如其他答案所建议的那样,执行此操作的 sed 方法是使用-i就地编辑。然而,这并不总是您想要的。-i将创建一个临时文件,然后用于替换原始文件。如果您的原始文件是链接(该链接将被常规文件替换),则会出现问题。如果需要保留链接,可以使用临时变量来存储 sed 的输出,然后再将其写回文件,如下所示:
tmp=$(sed 'code' file); echo -n "$tmp" > file
Run Code Online (Sandbox Code Playgroud)
更好的是,使用 useprintf而不是echosinceecho可能会\\像\在某些 shell 中一样进行处理(例如 dash):
tmp=$(sed 'code' file); printf "%s" "$tmp" > file
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
703227 次 |
| 最近记录: |