用tr删除反斜杠

  • 本文关键字:删除 tr bash macos tr
  • 更新时间 :
  • 英文 :


所以我从文件名中删除特殊字符并用空格替换。我所有的工作除了文件与单反斜杠包含在其中。注意,这些文件是在OS X的查找器中创建的

old_name="testingthisfolder"
new_name=$(echo $old_name | tr '<>:\#%|?*' ' ');

这会导致new_name为"testing hisolder"我怎么能只删除反斜杠而不删除前一个字符?

这导致new_name为"testing hisolder"

这个字符串看起来像echo -e "testingthisfolder"的结果,因为 tf实际上被替换为制表和表单输入控制字符

也许您有一个别名,如alias echo='echo -e',或者echo的实现在您的shell版本中解释反斜杠转义:

POSIX不需要支持任何选项,并且表示' echo '的行为是实现定义的,如果任何STRING包含反斜杠或者第一个参数是' -n '。便携式程序可以使用如果他们需要省略尾随换行符或输出,则使用' printf '命令控制字符或反斜杠

(来自信息页)

所以在新软件中应该使用printf而不是echo。特别是,echo $old_name应该替换为printf %s "$old_name"

例如,在这个讨论中有一个很好的解释。

不需要printf

正如@mklement0所建议的,您可以通过Bash here字符串来避免管道:

tr '<>:\#%|?*' ' ' <<<"$old_name"

Ruslan出色的回答解释了为什么您的命令可能不适合您,并提供了一个健壮的,可移植的解决方案。

tl;博士:

  • 您可能使用sh而不是bash运行代码(即使在macOS上sh是伪装的Bash),或者您显式打开了shell选项xpg_echo
  • 使用printf代替echo来实现可移植性。

在Bash中,使用默认选项并使用内置的echo,您的命令应该按原样工作(除了应该为健壮性对$old_name双引号),因为默认情况下echo不会在其操作数中展开转义序列,例如t。但是,Bash的echo 可以用来扩展控制字符转义序列:

    通过执行shopt -s xpg_echo 显式地
  • 隐式地,如果您以sh--posix选项运行Bash(在其他选项和行为更改中,该选项激活xpg_echo)

因此,您的症状可能是由从脚本中运行代码引起的,例如,在脚本中运行#!/bin/sh行。

然而,如果你的目标是sh,也就是说,如果你正在编写一个可移植的脚本,那么echo应该完全避免,因为它的行为在shell和平台上是不同的——参见Ruslan的printf解决方案。


作为题外话:也许tr命令更健壮的方法是白名单方法:仅声明结果中显式允许的字符,并使用-C选项排除其他字符:
old_name='testingthisfolder'
new_name=$(printf '%s' "$old_name" | tr -C '[:alnum:]_-' ' ')

这样,任何不是字母、数字、_-的字符都将被替换为空格。

对于Bash,您可以使用参数展开:

$ old_name="testingthisfolder"
$ new_name=${old_name//[<>:\#%|?*]/ }
$ echo $new_name
testing this folder

更多信息,请参考Bash手册中的shell参数扩展。

我认为您的测试用例缺少的适当转义,因此您并没有真正测试字符串中包含的反斜杠的情况。

这个为我工作:

old_name='testing\this\folder'
new_name=$(echo $old_name | tr '<>:\#%|?*' ' ');
echo $new_name
# testing this folder

最新更新