所以我从文件名中删除特殊字符并用空格替换。我所有的工作都与其中包含单个反斜杠的文件分开。 请注意,这些文件是在OS X上的Finder中创建的
old_name="testing\this\folder"
new_name=$(echo $old_name | tr '<>:\\#%|?*' ' ');
这导致new_name被“测试heolder” 我怎样才能删除反斜杠而不是前面的字符?
答案 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
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