用tr删除反斜杠

时间:2016-11-08 14:57:06

标签: bash macos tr

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

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

这导致new_name被“测试heolder” 我怎样才能删除反斜杠而不是前面的字符?

4 个答案:

答案 0 :(得分:4)

  

这会导致new_name成为“测试hisolder”

此字符串看起来像echo -e "testing\this\folder"的结果,因为 \t\f实际上已替换为制表符和换页控制字符

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

  

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

(来自信息页面)

因此,您应该在新软件中使用printf代替echo。特别是,echo $old_name应替换为printf %s "$old_name"

例如,在this discussion中有一个很好的解释。

无需printf

正如@ mklement0建议的那样,你可以通过Bash here string避免管道:

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

答案 1 :(得分:2)

使用Bash,您可以使用参数扩展:

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

有关详情,请参阅shell parameter expansion上的Bash手册。

答案 2 :(得分:2)

Ruslan's excellent answer解释了为什么您的命令可能不适合您并提供强大的便携式解决方案。

<强> TL;博士

  • 您可能使用sh而不是bash运行代码(即使在macOS sh上伪装成Bash),或者您明确打开了shell选项xpg_echo
  • 使用printf代替echo进行移植。

在Bash中,使用默认选项并使用echo内置函数,您的命令应该按原样运行(除了您应该引用$old_name以获得健壮性),因为echo默认情况下,在其操作数中展开转义序列,例如\t

但是,Bash的echo 可以扩展控制字符转义序列:

  • 明确地执行shopt -s xpg_echo
  • 隐式地,如果您将Bash作为sh--posix选项运行(其中包括其他选项和行为更改,则会激活xpg_echo

因此,您的症状可能是由于使用shebang行#!/bin/sh从脚本运行代码引起的。

但是,如果您定位sh,即如果您正在编写便携式脚本,那么应该完全避免使用echo它的行为在shell和平台上有所不同 - 请参阅Ruslan的printf解决方案。

顺便说一句:对tr命令采用更健壮的方法可能是白名单方法:仅说明结果中明确允许的字符,并使用{排除其他字符{1}}选项:

-C

这样,任何不包含字母,数字,old_name='testing\this\folder' new_name=$(printf '%s' "$old_name" | tr -C '[:alnum:]_-' ' ') _的字符都会替换为空格。

答案 3 :(得分:-1)

我认为您的测试用例缺少\的正确转义,所以您并没有真正测试字符串中包含反斜杠的情况。

这对我有用:

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