sed 在 FreeBSD 和 Linux 上的行为不同吗?

sed 在 FreeBSD 和 Linux 上的行为不同吗?

我同时使用 Linux 和 FreeBSD(具体来说,我使用 Debian Linux 和 PC-BSD),并且我发现sed.

我经常需要将“制表符分隔值”文件转换为“逗号分隔值”。我知道的最简单的方法是使用sed,如下所示:

sed 's/\t/,/g' inputFile.txt > outputFile.csv

这在 Linux 上完美运行:它用逗号替换每个选项卡...但在 FreeBSD 上,它不会替换任何内容!

我错过了什么吗? FreeBSD 上的语法是否sed与 Linux 上的语法不同?

答案1

也许你应该使用该-E选项(或-r如所解释的在手册上)以保持与 GNU Sed 的兼容性。对于您的情况,如果您习惯的话,您可以安装 Gnu Sed(端口格萨德在 FreeBSD 上),否则移植脚本将花费很长时间。

请记住。如果 BSD 上的某些命令的行为与该实用程序的 gnu 版本不同,这并不意味着它已损坏;)

答案2

是的,存在各种差异,的行为-i这是我唯一认识的人。

我从未使用过 BSD,所以我无法真正帮助解决细节,但解决方法可能是使用tr

tr '\t' , < inputFile.txt > outputFile.csv

一个令人愉快的副作用是速度tr应该明显更快。我在 Linux 上使用包含 50000 行的测试文件进行了测试,每行有 2 个选项卡:

$ time tr '\t' , < foo.txt > /dev/null 

real    0m0.004s
user    0m0.000s
sys     0m0.000s

$ time sed 's/\t/,/g' foo.txt > /dev/null 

real    0m0.039s
user    0m0.036s
sys     0m0.000s

答案3

是的,与 GNU 不同,sedFreeBSDsed不解释 ANSI C 转义序列,例如\t正则表达式中的转义序列。

在这种情况下获得最小公分母的一种方法是使用printf.

tab="$(printf '\t')"
printf '\t\n' | sed 's/'"${tab}"'/,/g'
printf '\t\n' | sed 's/'"$(printf '\t')"'/,/g'

如果开关或选项紧随其后,则sed -i就地文件编辑的行为可以兼容,例如适用于 GNU和 FreeBSD 。-ised -i -e 's/x/X/g' filesedsed

最新版本的 FreeBSD sed(FreeBSD 8.1 或更高版本)已-r切换以增加与 GNU 的兼容性sed

(此外,在正则表达式中使用 POSIX 字符类sed也是确保兼容性的好方法)。

对于符合 POSIX 标准的替代sed实现,请参阅:miniized - 更小、更便宜、更快的 SED 实施

答案4

登录后,我会看到下一条公告并保存。希望它对其他人也有用

想要使用 sed(1) 就地编辑文件吗?那么,要将名为“foo”的文件中的每个“e”替换为“o”,您可以执行以下操作:

sed -i.bak s/e/o/g foo

您将在名为“foo.bak”的文件中获得原始文件的备份,但如果您不想备份:

sed -i '' s/e/o/g foo

相关内容