Macos sed-i用于就地编辑的命令,可与GNU sed和BSD/OSX一起使用
我有一个makefile(为Linux上的Macos sed-i用于就地编辑的命令,可与GNU sed和BSD/OSX一起使用,macos,sed,gnu,inplace-editing,Macos,Sed,Gnu,Inplace Editing,我有一个makefile(为Linux上的gmake开发),我正试图将它移植到MacOS,但似乎sed不想合作。我要做的是使用GCC自动生成依赖项文件,然后使用sed稍微调整它们。生成文件的相关部分: $(OBJ\u DIR)/%.d:$(SRC\u DIR)/%.cpp $(CPPC)-MM-MD$
gmake
开发),我正试图将它移植到MacOS,但似乎sed
不想合作。我要做的是使用GCC
自动生成依赖项文件,然后使用sed
稍微调整它们。生成文件的相关部分
:
$(OBJ\u DIR)/%.d:$(SRC\u DIR)/%.cpp
$(CPPC)-MM-MD$<-o$@
sed-i的| \(.*)\.o:|$(OBJ\u DIR)/\1.o$(OBJ\u DIR)/\1.d$(TEST\u OBJ\u DIR)/\1\u utest.o:'$@
虽然这在GNU/Linux下运行没有问题,但在尝试在MacOS上构建时,我会遇到如下错误:
sed:1:“测试/obj/equipmentConta…”:未定义的标签“est/obj/equipmentContainer\u utest.d”
sed:1:“test/obj/dice_utest.d”:未定义的标签“est/obj/dice_utest.d”
sed:1:“test/obj/color-string_…”:未定义的标签“est/obj/color-string_utest.d”
似乎sed
正在切掉一个字符,但我看不出解决方案。处理-I
参数的方式与版本不同
通过以下方式添加-e
,您可以生成一个可能对这两者都“起作用”的命令:
#vv
sed-i-e的| \(.*)\.o:|$(OBJ\u DIR)/\1.o$(OBJ\u DIR)/\1.d$(TEST\u OBJ\u DIR)/\1\u utest.o:'$@
OSXsed-i
将-i
之后的下一个内容解释为就地编辑的备份副本的文件扩展名。(Linux版本仅在-i
和扩展名之间没有空格时才执行此操作。)显然,使用此操作的一个副作用是,您将获得一个备份文件,其中-e
作为扩展名,这可能是您不想要的。有关详细信息,请参阅此问题的其他答案,以及可以替代的更清洁的方法
您看到的行为是因为OS Xsed
将s | | |
作为扩展名(!)使用,然后将下一个参数解释为命令-在本例中,它以t
开始,该sed
将目标标签识别为参数的标签命令的分支-因此您会看到错误
如果您创建了一个文件test
,则可以重现错误:
$sed-i的| x | y |测试
sed:1:“测试”:未定义的标签“est”
实际上,正在做
sed-i-e“s/blah/blah/”文件
在MacOS中也无法实现您的期望。而是创建扩展名为-e
的备份文件
MacOS的正确命令是
sed-i”“-e”s/blah/blah/“文件
在Linux上,删除-i
和“
”之间的空格(请参阅)
sed-i”“-e”s/blah/blah/“文件
我也遇到了这个问题,并想到了以下解决方案:
darwin=false;
中的大小写“`uname`”
达尔文*)达尔文=真;;
以撒
如果是$darwin;然后
sedi=“/usr/bin/sed-i”
其他的
sedi=“sed-i”
fi
$sedi's/foo/bar/'/home/foobar/bar
为我工作;-),YMMV
我在一个多操作系统团队工作,ppl构建在Windows、Linux和OS X上。一些OS X用户抱怨,因为他们遇到了另一个错误——他们安装了sed的GNU端口,所以我必须指定完整路径 这并不是对这个问题的完全回答,但我们可以通过它获得与linux相当的行为
brew安装gnu sed
#添加到.bashrc/.zshrc
export PATH=“/usr/local/opt/gnu-sed/libexec/gnubin:$PATH”
(以前有一个
——使用默认名称选项brew安装gnu sed
,但最近已被删除)我已更正@thecarpy发布的解决方案:
下面是一个适用于sed-i
的跨平台解决方案:
sedi(){
案件$(联埃特派团)
达尔文*)sedi=('-i'');;
*)sedi='-i';;
以撒
LC_ALL=C sed“${sedi[@]}”“$@”
}
目前公认的答案在两个非常重要的方面存在缺陷
对于BSD sed(OSX版本),-e
选项被解释为
文件扩展名,因此创建了带有-e
分机
按照建议测试darwin内核不是一个可靠的方法
由于GNU或BSD sed可以
可以出现在任何数量的系统上
更可靠的测试是简单地测试--version
选项,该选项仅在sed的GNU版本中可用
sed--version>/dev/null 2>&1
一旦确定了sed的正确版本,我们就可以用正确的语法执行该命令
-i选项的GNU sed语法:
sed-i--“$@”
-i选项的BSD sed语法:
sed-i”““$@”
最后,将所有功能整合到一个跨平台功能中,以执行就地编辑:
sedi(){
sed--version>/dev/null 2>&1&&sed-i--“$@”sed-i“$@”
}
用法示例:
sedi's/old/new/g''some_file.txt'
此解决方案已经在OSX、Ubuntu、Freebsd、Cygwin、CentOS、Red Hat Enterprise和Msys上进行了测试 为问题[1]提供了一个很好的解释,但正如他所说的那样,解决方案可能会产生不必要的副作用
以下是无副作用的解决方案:
警告:单独解决-i
语法问题(如下所示)可能还不够,因为GNUsed
和BSD/macOSsed
之间存在许多其他差异(有关全面的讨论,请参阅我的)
使用-i
的解决方法:临时创建备份文件,然后将其清理:
使用非空后缀(备份文件文件扩展名)选项参数(不是空字符串的值),您可以通过将后缀直接附加到-i
选项,以一种既适用于BSD/macOSsed
又适用于GNUsed
的方式使用-i
这可用于创建bac