这应该非常简单,但由于某种原因它不起作用:
sed -i.bak -E 's/\t/ /' file.txt
它不是替换制表符,而是替换t
字符。我已经尝试了我能想到的所有变体,比如引用等等。我用谷歌搜索并发现其他所有人使用非常相似的表达方式,它们似乎对他们有用。
这-E
是 OS X 的事情。我认为失败可能是 OS X 的一些奇怪的怪癖造成的sed
,所以我也用 Ruby 尝试了它(没有-i
),并得到了相同的结果:
ruby -pe '$_.gsub!(/\t/," ")' < file.txt > file.new
我在 OS X 和 iTerm 上使用 Bash 3.2.51,尽管我看不出其中任何一个有什么关系。我没有设置任何奇怪的环境变量,尽管我可以发布您认为可能相关的任何变量。
可能出什么问题了?
更新:当我尝试 Ruby 版本时,我一定犯了一些其他错误或拼写错误,因为 Gilles 指出它做工作(而且我已经绝不让他误导了我!)。我不确定发生了什么,但我很确定这一定是我的错误。
答案1
sed 中制表符的语法\t
不是标准的。那个逃脱是一个GNU sed 扩展。您可以在网上找到很多使用它的示例,因为很多人使用 GNU sed(它是非嵌入式 Linux 上的 sed 实现)。但OS X sed与其他 *BSD sed 一样,不支持\t
制表符,而是将其视为\t
反斜杠后跟的含义t
。
解决方案有很多,例如:
使用文字制表符。
sed -i.bak 's/ / /' file.txt
使用
tr
或printf
产生制表符。sed -i.bak "s/$(printf '\t')/ /" file.txt sed -i.bak "s/$(echo a | tr 'a' '\t')/ /" file.txt
使用 bash 的允许反斜杠转义的字符串语法。
sed -i.bak $'s/\t/ /' file.txt
使用 Perl、Python 或 Ruby。您发布的 Ruby 代码片段确实有效。
答案2
使用 Bash 特定的引用它允许您像 C 中一样使用字符串,以便将真正的制表符传递给 sed,而不是转义序列:
sed -i.bak -E $'s/\t/ /' file.txt
答案3
sed -i $'s/\t/ /g' file.txt
在 OS X 上适用于我,并且与我一直在 Linux 上使用的命令相同。
答案4
如果您想要比 OS X 上的更强大sed
(支持\t
等),请安装GNU sed。