我同时使用 Linux 和 FreeBSD(具体来说,我使用 Debian Linux 和 PC-BSD),我发现sed
.
我经常需要将“制表符分隔值”文件转换为“逗号分隔值”。我知道的最简单的方法是使用sed
,像这样:
sed 's/\t/,/g' inputFile.txt > outputFile.csv
Run Code Online (Sandbox Code Playgroud)
这在 Linux 上非常有效:它用逗号替换每个选项卡......但在 FreeBSD 上,它不会替换任何东西!!!
我错过了什么吗?FreeBSD 的语法是否与sed
Linux的语法不同?
是的,有各种各样的差异,作为我唯一知道的一种行为-i
。
我从未使用过 BSD,所以我无法真正帮助了解细节,但可能会使用一种解决方法tr
:
tr '\t' , < inputFile.txt > outputFile.csv
Run Code Online (Sandbox Code Playgroud)
一个令人愉快的副作用是tr
应该明显更快。我使用一个包含 50000 行的测试文件在我的 Linux 上进行了测试,每个文件都有 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
Run Code Online (Sandbox Code Playgroud)
小智 5
是的,不像 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'
Run Code Online (Sandbox Code Playgroud)
sed -i
如果开关或选项紧跟在-i
开关之后,则就地文件编辑的行为可以兼容,例如,sed -i -e 's/x/X/g' file
适用于 GNUsed
和 FreeBSD sed
。
最新版本的 FreeBSD sed
(FreeBSD 8.1 或更高版本)具有-r
增加与 GNU 兼容性的开关sed
。
(此外,在sed
正则表达式中使用 POSIX 字符类也是确保兼容性的好方法)。
对于另一种符合 POSIX 的sed
实现,请参阅:最小化 - 更小、更便宜、更快的 SED 实现。