Bash 使用tr删除反斜杠
因此,我将从文件名中删除特殊字符并替换为空格。除了包含单个反斜杠的文件之外,我还有其他工作。 注意:这些文件是在OSX上的Finder中创建的Bash 使用tr删除反斜杠,bash,macos,tr,Bash,Macos,Tr,因此,我将从文件名中删除特殊字符并替换为空格。除了包含单个反斜杠的文件之外,我还有其他工作。 注意:这些文件是在OSX上的Finder中创建的 old_name="testing\this\folder" new_name=$(echo $old_name | tr '<>:\\#%|?*' ' '); old\u name=“testing\this\folder” 新名称=$(echo$旧名称| tr':\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\?*'')
old_name="testing\this\folder"
new_name=$(echo $old_name | tr '<>:\\#%|?*' ' ');
old\u name=“testing\this\folder”
新名称=$(echo$旧名称| tr':\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\?*'');
这导致新的_名称被“测试他的父亲”
如何删除反斜杠而不是前面的字符?对于Bash,可以使用参数展开:
$ old_name="testing\this\folder"
$ new_name=${old_name//[<>:\\#%|?*]/ }
$ echo $new_name
testing this folder
$old\u name=“测试\此\文件夹”
$new\u name=${old\u name/[:\\\\\\\\35;%\\\?*]/}
$echo$新名称
正在测试此文件夹
有关更多信息,请参阅上的Bash手册。我认为您的测试用例缺少对
\
的正确转义,因此您没有真正测试字符串中包含反斜杠的情况
这对我很有用:
old_name='testing\\this\\folder'
new_name=$(echo $old_name | tr '<>:\\#%|?*' ' ');
echo $new_name
# testing this folder
old\u name='testing\\this\\folder'
新名称=$(echo$旧名称| tr':\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\?*'');
echo$new_名称
#正在测试此文件夹
这导致新的_名称被“测试他的父亲”
此字符串看起来像是echo-e“测试\This\folder”
的结果,因为\t
和\f
实际上被制表符和表单提要控制字符替换
您可能有一个别名,如alias echo='echo-e'
,或者您的shell版本中的echo
的实现解释了反斜杠转义:
POSIX不需要支持任何选项,并表示
如果任何字符串包含
反斜杠或如果第一个参数为“-n”。可移植程序可以使用
如果需要省略尾随换行符或输出,则使用“printf”命令
控制字符或反斜杠
(从信息页面)
因此,您应该在新软件中使用printf
而不是echo
。特别是,echo$old\u name
应替换为printf%s“$old\u name”
例如,有一个很好的解释
无需printf
正如@mklement0所建议的,您可以通过以下方式避免管道:
tr':\\\\#%|?*'解释了为什么您的命令可能不适用于您,并提供了一个健壮、可移植的解决方案
tl;博士:
- 您可能在运行代码时使用了
sh
而不是bash
(即使在macOS上sh
是bash的伪装),或者您显式启用了shell选项xpg\u echo
李>
- 为了便于携带,请使用
printf
而不是echo
在Bash中,使用默认选项并使用内置的echo
时,命令应该按原样工作(除了为了稳健性,应该使用双引号$old\u name
),因为默认情况下echo
不会在其操作数中展开转义序列,例如\t
但是,可以使用Bash的echo
来扩展控制字符转义序列:
- 显式地,通过执行shopt-s xpg_echo
sh
或使用--posix
选项运行Bash(在其他选项和行为更改中,它会激活xpg\u echo
)#从脚本运行代码引起的/例如,bin/sh
但是,如果您的目标是sh
,也就是说,如果您正在编写一个可移植脚本,那么应该完全避免使用echo
,因为它的行为在不同的shell和平台上有所不同-请参阅Ruslan的printf
解决方案
顺便说一句:
tr
命令的一种更可靠的方法可能是白名单方法:只声明结果中明确允许的字符,并使用-C
选项排除其他字符:
old_name='testing\this\folder'
new_name=$(printf '%s' "$old_name" | tr -C '[:alnum:]_-' ' ')
这样,任何不是字母、数字、
\u
或-
的字符都会被替换为空格。根据您定义特殊字符的方式,您可以在Bash中使用类似于tr-d'[:punch:]'
的东西(问题是如何标记的),并使用默认选项,使用它的echo
内置项,这将保留两个反斜杠,结果字符串的单词之间将有2个空格。(相反,OP的代码应该按原样工作。)除此之外,$old_name
应该被双引号引用。您的转义只能在启用选项xpg_echo
时(隐式或显式)才起作用,但更好的解决方案是使用printf
或here-string。谢谢您的详细解释,这对我也不起作用
old_name='testing\this\folder'
new_name=$(printf '%s' "$old_name" | tr -C '[:alnum:]_-' ' ')