CRT*_*aze 26 osx sed gnu posix
所以我一直在 linux 上使用 'sed' 一段时间,但是在尝试在 OSX 上使用它时遇到了一些困难,因为 'POSIX sed' 和 'GNU sed' 有很多细微的差别。目前我正在努力解决如何在某个行号后插入一行文本。(在本例中,第 4 行)
在 linux 上,我会做这样的事情:
sed --in-place "4 a\ mode '0755'" file.txt
Run Code Online (Sandbox Code Playgroud)
所以在 OSX 上我试过这个:
sed -i "" "4 a\ mode '0755'" file.txt
Run Code Online (Sandbox Code Playgroud)
但是,这一直给我一个“命令末尾\ 后的额外字符”错误。任何想法这里有什么问题?我有错别字吗?还是我不明白 sed 版本之间的另一个区别?
jw0*_*013 27
严格来说,POSIX 规范sed
需要在 之后换行a\
:
Run Code Online (Sandbox Code Playgroud)[1addr]a\ text
如前所述将文本写入标准输出。
这使得编写单行有点痛的,这可能是由于以下原因GNU扩展的a
,i
和c
命令:
作为 GNU 扩展,如果在
a
和换行符之间存在非空格\
序列,则该行的文本,从 之后的第一个非空格字符开始a
,作为文本块的第一行。(这可以简化编写单行添加的脚本。)此扩展也适用于i
和c
命令。
因此,为了让您的sed
语法具有可移植性,您需要在a\
不知何故之后包含一个换行符。最简单的方法是插入一个带引号的换行符:
$ sed -e 'a\
> text'
Run Code Online (Sandbox Code Playgroud)
(其中$
和>
是 shell 提示)。如果你觉得很痛苦,bash
[1] 有$' '
插入 C 风格转义的引用语法,所以只需使用
sed -e 'a\'$'\n''text'
Run Code Online (Sandbox Code Playgroud)
[1] 和 mksh (r39b+) 以及一些非 bash bourne shell(例如,FreeBSD 9+ 中的 /bin/sh)
dub*_*jim 14
正如描述的这个答案,它使用sed的命令时,就像是有帮助的i
,并a
使用多个-e "..."
条款。这些子句中的每一个都将被理解为由换行符分隔。该i
和a
命令很难使用内嵌的sed脚本否则(他们是专为多行sed脚本文件使用调用使用sed -f file ...
)。看起来您不能使用-e
子句末尾引入的隐式换行符来分隔a\
要附加的文本行和文本行。但是您可以使用它来终止要附加的文本行。
在这种特定情况下,您尝试执行的操作实际上可能只需要一个-e ...
子句即可完成。您只需要a
正确使用该命令。根据 POSIX 标准,a
需要后跟 a \
,然后需要后跟换行符,然后将插入下一行的其余部分(直到遇到换行符或-e
子句结尾)。所以你可以这样做:
sed -i "" -e $'4 a\\\n'"mode '0755'" file.txt
Run Code Online (Sandbox Code Playgroud)
Perl 不会受到这种依赖于平台的 GNU 与非 GNU 与“专有”特性的影响。你可以这样做:
perl -ni.old -e 'print;if ($.==4) {print "mode 0755\n"}' file
Run Code Online (Sandbox Code Playgroud)
该-n' option creates a loop that reads every line of the input file. Unlike its cousin
-p (not used here) it doesn't automatically print every line read. The
-i invokes in-place replacement. The argument to
-i(viz. ".old") can be dropped or changed. It leaves a backup of the unmodified file. The -e
信号剧本的开头。
的$.
表示行数,与线-1开始。因此,命令行读取“文件”,当行号等于 4 时,它会打印该行,然后是您想要注入的任何内容。
我想赶紧补充一点,Perl 起源于sed
、AWK 和 C,因此简单替换等的语法并不是一个非常陡峭的学习曲线。