我同时使用 Linux 和 FreeBSD(具体来说,我使用 Debian Linux 和 PC-BSD),并且我发现sed
.
我经常需要将“制表符分隔值”文件转换为“逗号分隔值”。我知道的最简单的方法是使用sed
,如下所示:
sed 's/\t/,/g' inputFile.txt > outputFile.csv
这在 Linux 上完美运行:它用逗号替换每个选项卡...但在 FreeBSD 上,它不会替换任何内容!
我错过了什么吗? FreeBSD 上的语法是否sed
与 Linux 上的语法不同?
答案1
答案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 不同,sed
FreeBSDsed
不解释 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 。-i
sed -i -e 's/x/X/g' file
sed
sed
最新版本的 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