sed -i命令,用于就地编辑,以与GNU sed和BSD/OSX一起使用 [英] sed -i command for in-place editing to work with both GNU sed and BSD/OSX
问题描述
我有一个makefile(在Linux上是为gmake
开发的),试图将其移植到MacOS,但似乎sed
不想合作.我要做的是使用GCC
自动生成依赖项文件,然后使用sed
对其进行一些调整. makefile
:
I've got a makefile (developed for gmake
on Linux) that I'm attempting to port to MacOS, but it seems like sed
doesn't want to cooperate. What I do is use GCC
to autogenerate dependency files, and then tweak them a bit using sed
. The relevant portion of the makefile
:
$(OBJ_DIR)/%.d: $(SRC_DIR)/%.cpp
$(CPPC) -MM -MD $< -o $@
sed -i 's|\(.*\)\.o:|$(OBJ_DIR)/\1.o $(OBJ_DIR)/\1.d $(TEST_OBJ_DIR)/\1_utest.o:|' $@
尽管此程序在GNU/Linux下可以正常运行,但是在MacOS上尝试构建时却出现类似以下的错误:
While this runs with no trouble under GNU/Linux, I get errors like the following when attempting to build on MacOS:
sed: 1: "test/obj/equipmentConta ...": undefined label 'est/obj/equipmentContainer_utest.d'
sed: 1: "test/obj/dice_utest.d": undefined label 'est/obj/dice_utest.d'
sed: 1: "test/obj/color-string_u ...": undefined label 'est/obj/color-string_utest.d'
sed
似乎正在砍掉一个字符,但我看不到解决方案.
It would seem like sed
is chopping off a character, but I can't see the solution.
推荐答案
Linux 版本.
OS X sed
handles the -i
argument differently to the Linux version.
您可以通过添加-e
来生成可能对两者都起作用"的命令:
You can generate a command that might "work" for both by adding -e
in this way:
# vv
sed -i -e 's|\(.*\)\.o:|$(OBJ_DIR)/\1.o $(OBJ_DIR)/\1.d $(TEST_OBJ_DIR)/\1_utest.o:|' $@
OS X sed -i
将-i
之后的下一个内容解释为就地编辑的备份副本的文件扩展名. (Linux版本仅在-i
和扩展名之间没有空格的情况下执行此操作.)使用此功能的明显副作用是,您将获得以-e
作为扩展名的备份文件. .请参阅此问题的其他答案以获取更多详细信息,以及可以使用的更清洁的方法.
OS X sed -i
interprets the next thing after the -i
as a file extension for a backup copy of the in-place edit. (The Linux version only does this if there is no space between the -i
and the extension.) Obviously a side affect of using this is that you will get a backup file with -e
as an extension, which you may not want. Please refer to other answers to this question for more details, and cleaner approaches that can be used instead.
您看到的行为是因为OS X sed
使用s|||
作为扩展名(!),然后将 next 参数解释为命令-在这种情况下,它以t
开头,sed
会将其识别为期望目标标签作为参数的分支到标签"命令-因此您会看到错误.
The behaviour you see is because OS X sed
consumes the s|||
as the extension (!) then interprets the next argument as a command - in this case it begins with t
, which sed
recognizes as a branch-to-label command expecting the target label as an argument - hence the error you see.
如果创建文件test
,则可以重现该错误:
If you create a file test
you can reproduce the error:
$ sed -i 's|x|y|' test
sed: 1: "test": undefined label 'est'
这篇关于sed -i命令,用于就地编辑,以与GNU sed和BSD/OSX一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!