我可以使用`sed`来翻译像`tr`这样的字符吗?

n.s*_*.st 16 sed tr

我想用另一组中的相应字符替换一组字符,如下所示:

original set: ots
"target" set: u.x

foobartest ? fuubar.ex.
Run Code Online (Sandbox Code Playgroud)

像这样的翻译/音译是tr命令的特色:

$ echo 'foobartest' | tr 'ots' 'u.x'
fuubar.ex.
Run Code Online (Sandbox Code Playgroud)

不幸的是,tr它不支持像sed这样就地更改文件。
我想使用sed这样我就不必重新发明处理临时文件的轮子了。

n.s*_*.st 28

sed有这样的y命令tr

$ echo 'foobartest' | sed 'y/ots/u.x/'
fuubar.ex.
Run Code Online (Sandbox Code Playgroud)

y命令是POSIXsed规范的一部分,因此它应该适用于几乎任何平台。

并且因为它是sed,你可以让它用它的编辑版本替换一个文件,省去麻烦的临时文件业务(假设你的实现sed支持该-i选项,这不是由 POSIX 指定的):

$ sed -i 'y/ots/u.x/' some-file.txt
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 8

如果就像你的情况一样,你在不改变它们的大小的情况下音译字符(无论如何,像 GNU 这样的一些实现tr只支持单字节字符),你可以这样做:

tr 'ots' 'u.x' < file 1<> file
Run Code Online (Sandbox Code Playgroud)

也就是说,已经tr覆盖文件本身。

这比sed -i几个帐户要好:

  • 它不需要额外的磁盘空间(除了一些稀疏文件,写时复制的特殊情况)
  • 它保留 inode 编号、所有权、权限、ACL...
  • 它适用于符号链接,不会破坏硬链接
  • 它不会在被杀死时留下临时文件。

一个缺点是,如果它被中断,文件最终会被翻译一半(但在这种情况下,您可以再次运行以完成它)。一些sed实现会通过确保原始文件保持不变来正确处理,除非命令成功。

  • 如果您在翻译集中有递归,请小心重新运行翻译,例如`echo 'abc' | tr ab bx`。 (3认同)