Bash字符串用一个替换多个字符

neu*_*ino 10 shell bash string

我正在从提要标题中替换除字母和数字以外的所有字符,并使用破折号将结果用作任何文件系统的安全文件名:

$ t="Episodie 06: No hope of riding home (NEW) - Advanced grammar"
$ echo ${t//[^A-Za-z0-9]/-}
Episodie-06--No-hope-of-riding-home--NEW----Advanced-grammar
Run Code Online (Sandbox Code Playgroud)

但是我想用一个像压缩所有重复的破折号 Episodie-06-No-hope-of-riding-home-NEW-Advanced-grammar

我发现我可以使用两遍替换来实现它:

$ t="Episodie 06: No hope of riding home (NEW) - Advanced grammar"
$ tmp=${t//[^A-Za-z0-9]/-}
$ echo ${tmp//--/-}
Episodie-06-No-hope-of-riding-home-NEW--Advanced-grammar
Run Code Online (Sandbox Code Playgroud)

我以为我可以一次性完成,例如:

$ echo ${t//[^A-Za-z0-9]+/-}
Run Code Online (Sandbox Code Playgroud)

但它不起作用。

有什么线索吗?

注意:我不想使用sed或其他工具

Gil*_*il' 11

您需要比传统 shell 通配符更强大的东西。在 bash 中,设置该extglob选项,它使您可以通过从 ksh 继承的异常语法访问glob 模式中的正则表达式。

shopt -s extglob
sanitized=${raw//+([^A-Za-z0-9])/-}
Run Code Online (Sandbox Code Playgroud)


gle*_*man 7

tr 是这项工作的好工具

new=$( printf "%s" "$t" | tr -cs 'a-zA-Z0-9' '-' )
new=${new#-}; new=${new%-}
Run Code Online (Sandbox Code Playgroud)