尝试使用sed替换文件内容,替换工作,但由于某种原因,我在结果输出文件的末尾获得额外的空格,导致文件在打开的应用程序中不可读/不可查看。
我的命令如下:
for file in *.example ; do LANG=C sed -i "" "s|https://foo.bar|http://foo.bar|g" "$file" ; done
答案 0 :(得分:1)
我建议更换
\foo.bar
通过
foo.bar
答案 1 :(得分:0)
事后看来:
BSD / macOS sed
从根本上不适合在二进制文件中进行替换,因为总是在每个输出命令中输出一个尾随\n
(换行符)。
相比之下, GNU sed
没有此问题,因为它 - 值得称道 - 只有在输入时附加\n
“行“也有一个。
请注意,换行符分隔线的概念并不真正适用于二进制输入:换行可能存在也可能不存在,并且可能存在大块数据。在最坏的情况下,整个输入将立即读取 。 [1]
您可以使用以下命令测试此行为:
sed -n 'p' <(printf 'x') | cat -et # input printf 'x' has no trailing \n
输出x$
表示添加了换行符($
符号cat -et
)(BSD Sed),而x
表示它不是(GNU Sed) )。
因此,鉴于您使用的是macOS,可以使用Homebrew使用brew install gnu-sed
安装GNU Sed,然后使用以下命令:
LANG=C gsed -i 's|https://foo.bar|http://foo.bar|g' *.example
Homebrew将GNU Sed安装为gsed
,以便与 macOS的股票(BSD)sed
一起存在。
LANG=C
(稍微更强大:LC_ALL=C
)需要通过原样传递二进制输入的所有字节,而不会导致二进制字节无法识别为有效的问题< EM>字符的)。
请注意,此方法将您限制为替换中的仅ASCII字符(除非您明确将字节值添加为转义序列)。
请注意不同的,不兼容的-i
语法,用于就地更新无备份 - 否(单独)选项 - 参数;请参阅我的this answer了解背景信息。
注意如何在Sed脚本周围使用'...'
(单引号),这通常是可取的,因为它避免了前面发生的shell扩展和Sed最终看到的内容之间的混淆。
[1]除了内存使用之外,在这里使用Sed的默认行解析行为是很好的,因为你的替换命令与换行符不匹配。但是,如果要将输入分解为NUL中的“行”(并且还在输出中使用NUL),则可以使用GNU Sed的-z
选项。